"""
Idea from: https://github.com/cczu-osa/aki
"""
import json
from nonebot.adapters.cqhttp import Bot, MessageEvent

from ATRI.rule import is_in_service
from ATRI.service import Service as sv
from ATRI.utils.request import post_bytes
from ATRI.exceptions import RequestTimeOut


RUN_API_URL_FORMAT = "https://glot.io/run/{}?version=latest"
SUPPORTED_LANGUAGES = {
    "assembly": {"ext": "asm"},
    "bash": {"ext": "sh"},
    "c": {"ext": "c"},
    "clojure": {"ext": "clj"},
    "coffeescript": {"ext": "coffe"},
    "cpp": {"ext": "cpp"},
    "csharp": {"ext": "cs"},
    "erlang": {"ext": "erl"},
    "fsharp": {"ext": "fs"},
    "go": {"ext": "go"},
    "groovy": {"ext": "groovy"},
    "haskell": {"ext": "hs"},
    "java": {"ext": "java", "name": "Main"},
    "javascript": {"ext": "js"},
    "julia": {"ext": "jl"},
    "kotlin": {"ext": "kt"},
    "lua": {"ext": "lua"},
    "perl": {"ext": "pl"},
    "php": {"ext": "php"},
    "python": {"ext": "py"},
    "ruby": {"ext": "rb"},
    "rust": {"ext": "rs"},
    "scala": {"ext": "scala"},
    "swift": {"ext": "swift"},
    "typescript": {"ext": "ts"},
}


__doc__ = """
在线运行代码
权限组：所有人
用法：
  /code (lang) (code)
示例：
  /code python
  print('Hello world!')
"""

code_runner = sv.on_command(cmd="code", docs=__doc__, rule=is_in_service("code"))


@code_runner.handle()
async def _code_runner(bot: Bot, event: MessageEvent) -> None:
    msg = str(event.message).split("\n")

    if msg[0] == "list":
        msg0 = "咱现在支持的语言如下：\n"
        msg0 += ", ".join(map(str, SUPPORTED_LANGUAGES.keys()))

        await code_runner.finish(msg0)
    elif not msg[0]:
        await code_runner.finish("请键入/help以获取更多支持...")

    laug = msg[0].replace("\r", "")
    if laug not in SUPPORTED_LANGUAGES:
        await code_runner.finish("该语言暂不支持...")

    del msg[0]
    code = "\n".join(map(str, msg))
    try:
        req = await post_bytes(
            RUN_API_URL_FORMAT.format(laug),
            json={
                "files": [
                    {
                        "name": (
                            SUPPORTED_LANGUAGES[laug].get("name", "main")
                            + f".{SUPPORTED_LANGUAGES[laug]['ext']}"
                        ),
                        "content": code,
                    }
                ],
                "stdin": "",
                "command": "",
            },
        )
    except RequestTimeOut:
        raise RequestTimeOut("Failed to request!")

    payload = json.loads(req)
    sent = False
    for k in ["stdout", "stderr", "error"]:
        v = payload.get(k)
        lines = v.splitlines()
        lines, remained_lines = lines[:10], lines[10:]
        out = "\n".join(lines)
        out, remained_out = out[: 60 * 10], out[60 * 10 :]

        if remained_lines or remained_out:
            out += f"\n（太多了太多了...）"

        if out:
            await bot.send(event, f"{k}:\n\n{out}")
            sent = True

    if not sent:
        await code_runner.finish("Running success! Nothing print.")
