# -*- coding: utf-8 -*-

from ddans.native.hook import NHook
from ddans.terminal import Terminal

DEF_ARGS = ['>']


class ArgsParser:

    def __init__(self):
        self.args = {}
        self.actions = {}
        self.types = {}
        for arg in DEF_ARGS:
            self.add_def(arg)

    def __getitem__(self, key):
        return self.actions.get(key)

    def __getattr__(self, attr):
        return self.get_val(attr)

    def get_value(self, *args, default=None):
        if (len(args) <= 0):
            return default

        key = args[0]
        count = len(args[1:])
        _val = self.get_val(key) if NHook.isvalid_str(key) else None
        if _val is None:
            return default if count <= 0 else self.get_value(*args[1:],
                                                             default=default)
        elif key in self.args and NHook.is_instance(
                _val, self.args[key].get('type')):
            return _val
        else:
            return default if count <= 0 else self.get_value(*args[1:],
                                                             default=default)

    def get_bool(self, *args):
        return self.get_value(*args, default=False)

    def get_val(self, key):
        return self.actions.get(key) or self.get_default(key)

    def get_default(self, key):
        if key in self.args:
            return self.args.get(key).get('default')
        else:
            return None

    def add_argument(self,
                     action: str,
                     short: str = '',
                     type=str,
                     help=None,
                     default=None):
        if not NHook.isvalid_str(action):
            return

        _short = short if NHook.isvalid_str(short) else None
        self.args[action] = {
            'type': type,
            'help': help,
            'action': action,
            'short': _short,
            'is_short': False,
            'is_def': False,
            'default': default
        }
        self.types[action] = type

        if _short is None:
            return

        self.args[_short] = {
            'type': type,
            'help': help,
            'action': _short,
            'short': None,
            'is_short': True,
            'is_def': False,
            'default': default
        }
        self.types[_short] = type

    def add_def(self, action: str, type=str, default=''):
        self.args[action] = {
            'type': type,
            'help': '',
            'action': action,
            'short': None,
            'is_short': False,
            'is_def': True,
            'default': default,
        }
        self.types[action] = type

    def reset(self):
        self.actions = {}

    def parse(self, *args):
        self.reset()
        argv = NHook.to_list(args)
        current_arg = None

        # 遍历命令行参数列表
        for i, arg in enumerate(argv, start=0):
            # 如果参数以 - 或 -- 开头
            if arg.startswith('-'):
                # 如果参数以 -- 开头
                if arg.startswith('--'):
                    # 去掉开头的 --，得到参数名
                    current_arg = arg[2:]
                    # 如果参数包含等号，则提取参数值
                    if '=' in current_arg:
                        name, value = current_arg.split('=', 1)
                        self.actions[name] = self._convert_value(name, value)
                    else:
                        self.actions[current_arg] = True  # 没有等号，则视为布尔标志参数
                        current_arg = None
                # 如果参数以 - 开头
                else:
                    # 去掉开头的 -，得到参数名
                    current_arg = arg[1:]
                    # 如果下一个参数不以 - 开头且不是最后一个参数，则作为参数值
                    if i < len(argv) - 1 and not argv[i + 1].startswith('-'):
                        self.actions[current_arg] = self._convert_value(
                            current_arg, argv[i + 1])
                        current_arg = None
                    else:
                        self.actions[current_arg] = True
            elif DEF_ARGS.count(arg) > 0:
                current_arg = arg
                # 如果下一个参数不以 - 开头且不是最后一个参数，则作为参数值
                if i < len(argv) - 1 and not argv[i + 1].startswith('-'):
                    self.actions[current_arg] = self._convert_value(
                        current_arg, argv[i + 1])
                    current_arg = None
                else:
                    self.actions[current_arg] = True
            # 如果当前有参数名，则存储参数值到字典中
            elif current_arg:
                self.actions[current_arg] = self._convert_value(
                    current_arg, arg)
                current_arg = None
            # 如果当前没有参数名，则直接存储参数到字典中
            else:
                self.actions[arg] = True

    def _convert_value(self, name, value):
        try:
            value = value.strip("'\"")
            if name in self.types:
                return self.types[name](value)
            return None
        except Exception:
            return None

    def usage(self):
        for name, info in self.args.items():
            if info.get('is_short') or info.get("is_def"):
                continue
            help_text = info['help'] or ''
            action_text = info['action'] or name
            short_text = info['short']
            if short_text is None:
                Terminal.print(f"    --{action_text}: {help_text}")
            else:
                Terminal.print((f"    --{action_text} | -{short_text}:"
                                f" {help_text}"))
