from ..aamgr import AbstractCommandNode, Context

import os

import pkg.plugin.host as plugin_host
import pkg.utils.updater as updater


@AbstractCommandNode.register(
    parent=None,
    name="plugin",
    description="插件管理",
    usage="!plugin\n!plugin get <插件仓库地址>\n!plugin update\n!plugin del <插件名>\n!plugin on <插件名>\n!plugin off <插件名>",
    aliases=[],
    privilege=2
)
class PluginCommand(AbstractCommandNode):
    @classmethod
    def process(cls, ctx: Context) -> tuple[bool, list]:
        reply = []
        plugin_list = plugin_host.__plugins__
        if len(ctx.params) == 0:
            # 列出所有插件
            
            reply_str = "[bot]所有插件({}):\n".format(len(plugin_host.__plugins__))
            idx = 0
            for key in plugin_host.iter_plugins_name():
                plugin = plugin_list[key]
                reply_str += "\n#{} {} {}\n{}\nv{}\n作者: {}\n"\
                    .format((idx+1), plugin['name'],
                            "[已禁用]" if not plugin['enabled'] else "",
                            plugin['description'],
                            plugin['version'], plugin['author'])

                if updater.is_repo("/".join(plugin['path'].split('/')[:-1])):
                    remote_url = updater.get_remote_url("/".join(plugin['path'].split('/')[:-1]))
                    if remote_url != "https://github.com/RockChinQ/QChatGPT" and remote_url != "https://gitee.com/RockChin/QChatGPT":
                        reply_str += "源码: "+remote_url+"\n"

                idx += 1

            reply = [reply_str]
            return True, reply
        elif ctx.params[0].startswith("http"):
            reply = ["[bot]err: 此命令已弃用，请使用 !plugin get <插件仓库地址> 进行安装"]
            return True, reply
        else:
            return False, []

    
@AbstractCommandNode.register(
    parent=PluginCommand,
    name="get",
    description="安装插件",
    usage="!plugin get <插件仓库地址>",
    aliases=[],
    privilege=2
)
class PluginGetCommand(AbstractCommandNode):
    @classmethod
    def process(cls, ctx: Context) -> tuple[bool, list]:
        import threading
        import logging
        import pkg.utils.context

        if len(ctx.crt_params) == 0:
            reply = ["[bot]err: 请提供插件仓库地址"]
            return True, reply
        
        reply = []
        def closure():
            try:
                plugin_host.install_plugin(ctx.crt_params[0])
                pkg.utils.context.get_qqbot_manager().notify_admin("插件安装成功，请发送 !reload 指令重载插件")
            except Exception as e:
                logging.error("插件安装失败:{}".format(e))
                pkg.utils.context.get_qqbot_manager().notify_admin("插件安装失败:{}".format(e))

        threading.Thread(target=closure, args=()).start()
        reply = ["[bot]正在安装插件..."]
        return True, reply


@AbstractCommandNode.register(
    parent=PluginCommand,
    name="update",
    description="更新所有插件",
    usage="!plugin update",
    aliases=[],
    privilege=2
)
class PluginUpdateCommand(AbstractCommandNode):
    @classmethod
    def process(cls, ctx: Context) -> tuple[bool, list]:
        import threading
        import logging
        plugin_list = plugin_host.__plugins__

        reply = []

        if len(ctx.crt_params) > 0:
            def closure():
                try:
                    import pkg.utils.context
                    
                    updated = []

                    if ctx.crt_params[0] == 'all':
                        for key in plugin_list:
                            plugin_host.update_plugin(key)
                            updated.append(key)
                    else:
                        if ctx.crt_params[0] in plugin_list:
                            plugin_host.update_plugin(ctx.crt_params[0])
                            updated.append(ctx.crt_params[0])
                        else:
                            raise Exception("未找到插件: {}".format(ctx.crt_params[0]))

                    pkg.utils.context.get_qqbot_manager().notify_admin("已更新插件: {}, 请发送 !reload 重载插件".format(", ".join(updated)))
                except Exception as e:
                    logging.error("插件更新失败:{}".format(e))
                    pkg.utils.context.get_qqbot_manager().notify_admin("插件更新失败:{} 请尝试手动更新插件".format(e))

            reply = ["[bot]正在更新插件，请勿重复发起..."]
            threading.Thread(target=closure).start()
        else:
            reply = ["[bot]请指定要更新的插件, 或使用 !plugin update all 更新所有插件"]
        return True, reply


@AbstractCommandNode.register(
    parent=PluginCommand,
    name="del",
    description="删除插件",
    usage="!plugin del <插件名>",
    aliases=[],
    privilege=2
)
class PluginDelCommand(AbstractCommandNode):
    @classmethod
    def process(cls, ctx: Context) -> tuple[bool, list]:
        plugin_list = plugin_host.__plugins__
        reply = []

        if len(ctx.crt_params) < 1:
            reply = ["[bot]err: 未指定插件名"]
        else:
            plugin_name = ctx.crt_params[0]
            if plugin_name in plugin_list:
                unin_path = plugin_host.uninstall_plugin(plugin_name)
                reply = ["[bot]已删除插件: {} ({}), 请发送 !reload 重载插件".format(plugin_name, unin_path)]
            else:
                reply = ["[bot]err:未找到插件: {}, 请使用!plugin指令查看插件列表".format(plugin_name)]
        
        return True, reply


@AbstractCommandNode.register(
    parent=PluginCommand,
    name="on",
    description="启用指定插件",
    usage="!plugin on <插件名>",
    aliases=[],
    privilege=2
)
@AbstractCommandNode.register(
    parent=PluginCommand,
    name="off",
    description="禁用指定插件",
    usage="!plugin off <插件名>",
    aliases=[],
    privilege=2
)
class PluginOnOffCommand(AbstractCommandNode):
    @classmethod
    def process(cls, ctx: Context) -> tuple[bool, list]:
        import pkg.plugin.switch as plugin_switch

        plugin_list = plugin_host.__plugins__
        reply = []
        
        print(ctx.params)
        new_status = ctx.params[0] == 'on'

        if len(ctx.crt_params) < 1:
            reply = ["[bot]err: 未指定插件名"]
        else:
            plugin_name = ctx.crt_params[0]
            if plugin_name in plugin_list:
                plugin_list[plugin_name]['enabled'] = new_status
                plugin_switch.dump_switch()
                reply = ["[bot]已{}插件: {}".format("启用" if new_status else "禁用", plugin_name)]
            else:
                reply = ["[bot]err:未找到插件: {}, 请使用!plugin指令查看插件列表".format(plugin_name)]
        
        return True, reply

