import argparse
import sys, os
from typing import List
import textwrap
import argparse
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import core.logger as logger
from utils.utils import get_alkaid_root
log = logger.get_logger()
from database.base import BaseConfig, AutoInstanceDecorator

class ConfigureStyleHelpFormatter(argparse.HelpFormatter):
    """自定义的帮助信息格式化类，用于美化 argparse 的帮助输出
    
    特点：
    1. 带有彩色标记的输出样式
    2. 优化了选项和描述的对齐
    """
    
    # 颜色代码定义
    BLUE = "\033[1;34m"   # 蓝色，用于位置参数
    GREEN = "\033[1;32m"  # 绿色，用于普通选项
    YELLOW = "\033[1;33m" # 黄色，用于必选参数
    RESET = "\033[0m"     # 重置颜色
    
    def __init__(self, prog, indent_increment=2, max_help_position=8, width=None):
        # 根据终端宽度自动调整
        try:
            width = width or min(120, os.get_terminal_size().columns)
        except OSError:
            width = width or 120  # 使用默认宽度
        super().__init__(prog, indent_increment, max_help_position, width)
    
    def _format_action_invocation(self, action):
        """格式化参数选项的显示方式，添加彩色显示"""
        if not action.option_strings:
            # 位置参数，显示为蓝色
            metavar, = self._metavar_formatter(action, action.dest)(1)
            return f"{self.BLUE}{metavar}{self.RESET}"

        # 处理可选参数
        parts = []
        
        # 判断是否为必选参数，是则使用黄色，否则使用绿色
        color = self.YELLOW if action.required else self.GREEN

        # 如果同时有短选项和长选项
        if len(action.option_strings) > 1:
            short, long = action.option_strings
            parts.append(f"{color}{short}{self.RESET}, {color}{long}{self.RESET}")
        else:
            # 只有一个选项
            parts.append(f"{color}{action.option_strings[0]}{self.RESET}")

        # 添加 metavar（如果有）
        if action.metavar is not None:
            parts.append(f" {action.metavar}")
        elif action.nargs != 0:
            parts.append(f" {action.dest.upper()}")

        return ''.join(parts)
    
    def add_usage(self, usage, actions, groups, prefix=None):
        """重写帮助信息的用法部分，优化了显示格式"""
        if prefix is None:
            prefix = 'usage: '
        return super().add_usage(usage, actions, groups, prefix)
    
    def _format_action(self, action):
        """重写格式化动作方法，确保帮助文本正确对齐和显示"""
        # 获取基础格式化的帮助文本
        result = super()._format_action(action)
        
        # 如果有choices且不是帮助动作，则添加选项信息
        if hasattr(action, 'choices') and action.choices and action.option_strings:
            # 查找最后一个换行符后的位置
            last_line_start = result.rfind('\n') + 1
            # indentation = ' ' * (last_line_start - result.rfind('\n', 0, last_line_start - 1) - 1)
            indentation = ' ' * 8
            
            # 格式化choices选项
            choices_str = f"{indentation}  可选值: {', '.join([str(c) for c in action.choices])}"
            result = f"{result}\n{choices_str} \n"
            
        return result
    
    def _split_lines(self, text, width):
        """优化帮助文本的换行处理"""
        if not text:
            return []
        if '\n' in text:
            # 开头的文本按原样分行显示
            ret = []
            for _ in text.splitlines():
                _ = _.strip()
                ret.append(_[1:] if _[0] == '|' else _)
            return ret
        # 正常文本使用 textwrap 换行
        return textwrap.wrap(text, width)
        
    def _fill_text(self, text, width, indent):
        """优化帮助文本的填充显示"""
        if not text:
            return ""
        # 使用textwrap对文本进行缩进和填充
        text = self._whitespace_matcher.sub(' ', text).strip()
        paragraphs = text.split('.\n ')
        multi_paragraphs = '\n'.join([textwrap.fill(p, width) for p in paragraphs])
        return textwrap.indent(multi_paragraphs, indent)


@AutoInstanceDecorator
class ReleaseOptions(BaseConfig):
    """Release 选项

    Args:
        SkipCheckout (bool, optional): 是否跳过checkout kernel/mboot 的操作. Defaults to False.
        OpenSource (bool, optional): 
            #是否开启SDK开源模式:
            #闭源模式: MI编译为lib和ko对外提供功能
            #开源模式:MI源码发布, 客户可直接获得MI原始代码
            #   开源的list:
            #    sdk/interface/src/vpe/
            #    sdk/interface/src/venc/
            #    sdk/impl/vpe
            #    sdk/impl/venc/. Defaults to False.
        Cm4Support (bool, optional): 支持release CM4. Defaults to False.
        RiscVSupport (bool, optional): 支持release RiscV. Defaults to False.
        MounRiverSDK (int, optional): 选择MounRiver SDK版本. Defaults to 0.
        ThreadNum (int, optional): 编译线程数. Defaults to 1.
        Doc2Pdf (bool, optional): 编译文档为pdf格式. Defaults to False.
        VerifyBuild (bool, optional): 验证编译结果. Defaults to False.
        Doc2Html (bool, optional): 编译文档为html格式. Defaults to False.
        ReduceCodeSize (bool, optional): 减小编译代码大小. Defaults to False.
        SkipSyncCode (bool, optional): 跳过代码同步. Defaults to False.
        Ipl_version (str, optional): 选择IPL版本. Defaults to "CN".
    """
    _config = {
        # 必需参数
        "SWBoardAlias": "",  # -a: 板子别名
        "TagId": "",  # -t: 标签ID
        "SnapShotXml": "",  # -s: 快照XML文件
        "SWBoardType": "",  # -b: 板子类型
        "SWProductType": "",  # -p: 产品类型

        # 可选参数
        "AlkaidRootPath": '',  # 仓库根路径
        "DocsPath": "",  # -d: 文档路径
        "HWChipType": "",  # -c: 硬件芯片类型
        "HWPackageType": "",  # -k: 硬件包类型
        "OutPath": "",  # -o: 输出路径
        "ThreadNum": 1,  # -j: 线程数
        "IplVersion": "CN",  # -l: IPL版本

        # 布尔参数
        "SkipCheckout": False,  # -i: 跳过从bin检出kernel/mboot
        "OpenSource": False,  # -f: 开放源代码
        "MounRiverSDK": False,  # -m: 启用RiscVSupport时支持MounRiverSDK
        "RiscVSupport": False,  # -n: 支持riscv源码
        "Cm4Support": False,  # -y: 支持cm4源码
        "Doc2Pdf": False,  # -z: 文档转换为pdf
        "Doc2Html": False,  # -h: 文档转换为html
        "VerifyBuild": False,  # -v: 验证构建
        "ReduceCodeSize": False,  # -u: 减小代码大小
        "SkipSyncCode": False,  # -x: 跳过通过快照XML同步代码
        "OpenRtosWhiteList": False,  # -X: 开放所有rtos白名单
        "OpenCm4WhiteList": False,  # -Y: 开放所有cm4白名单
    }

    def __init__(self):
        super().__init__()
        parser = argparse.ArgumentParser(description='Sigmastar Release SDK Options',
                                         formatter_class=ConfigureStyleHelpFormatter,
                                         epilog= "more help info see: http://xxxxxx",
                                         add_help=False) #-hhelp 信息被占用了
        add = parser.add_argument
        add('-a', '--SWBoardAlias'  , required=True, type=str, help='板子别名 iford souffle muffin...')
        add('-t', '--TagId'         , required=True, type=str, help='Release的Tag')
        add('-s', '--SnapShotXml'   , required=True, type=str, help='Alkaid仓库快照XML文件')
        add('-b', '--SWBoardType'   , required=True, type=str, help='板子类型')
        add('-p', '--SWProductType' , required=True, type=str, help='Release产品类型列表')
        add('-r', '--AlkaidRootPath', default = get_alkaid_root(), type=str, help='Alkaid仓库根目录路径')
        add('-d', '--DocsPath'      , default = '', type=str, help='文档路径')
        add('-c', '--HWChipType'    , default = '', type=str, help='硬件芯片类型')
        add('-k', '--HWPackageType' , default = '', type=str, help='硬件封装类型')
        add('-o', '--OutPath'       , default = "release", type=str, help='Release输出路径')
        add('-j', '--ThreadNum'     , default = 1, type=int, help='编译使用的线程数')
        add('-i', '--SkipCheckout'  , default = False, action = "store_true", help='跳过从bin检出kernel/mboot')
        add('-f', '--OpenSource'    , default = False, action = "store_true",
            help="""是否开启SDK开源模式:
            |  闭源模式: MI编译为lib和ko对外提供功能
            |  开源模式: MI源码发布, 客户可直接获得MI原始代码""")
        add('-n', '--RiscVSupport'  , default = False, action = "store_true", help='支持riscv源码')
        add('-y', '--Cm4Support'    , default = False, action = "store_true", help='支持cm4源码')
        add('-m', '--MounRiverSDK'  , default = False, action = "store_true", help='启用RiscVSupport时支持MounRiverSDK')
        add('-z', '--Doc2Pdf'       , default = False, action = "store_true", help='将文档转换为PDF格式')
        add('-l', '--IplVersion'    , default = "CN", type=str, choices=["CN", "WW"], help='选择IPL版本')
        add('-h', '--Doc2Html'      , default = False, action = "store_true", help='将文档转换为HTML格式')
        add('-v', '--VerifyBuild'   , default = False, action = "store_true", help='验证构建')
        add('-u', '--ReduceCodeSize', default = False, action = "store_true", help='减小代码体积')
        add('-x', '--SkipSyncCode'  , default = False, action = "store_true", help='跳过通过快照XML同步代码')
        add('--help', action='help', help='显示帮助信息')
        add('--log', type=str,choices=['error', 'warn', 'info', 'debug', 'trace'], default='info', help='设置日志级别')
        self.parser = parser

    def parse(self, args:List[str]):
        args = self.parser.parse_args(args)
        for k,v in args.__dict__.items():
            if k.startswith('__'):
                continue
            self[k] = v
    def check(self) -> bool:
        """
        检查参数配置是否合法
        """
        # 检查必需参数
        required_params = ["SWBoardAlias", "TagId", "SWBoardType", "SWProductType"]
        for param in required_params:
            if not self[param]:
                raise ValueError(f"必需参数 {param} 不能为空")

        # 检查数值参数
        if not isinstance(self.ThreadNum, int) or self.ThreadNum <= 0:
            raise ValueError("ThreadNum 必须为正整数")

        # 检查布尔参数
        bool_params = [
            "SkipCheckout", "OpenSource", "RiscVSupport", "Cm4Support",
            "Doc2Pdf", "Doc2Html", "VerifyBuild", "ReduceCodeSize",
            "SkipSyncCode", "OpenRtosWhiteList", "OpenCm4WhiteList", "MounRiverSDK"
        ]
        for param in bool_params:
            if not isinstance(self[param], bool):
                raise ValueError(f"参数 {param} 必须为布尔值")
        # 检查快照XML文件是否存在
        if not self.SkipSyncCode and not self.SnapShotXml:
            raise ValueError("SnapShotXml is required when SkipSyncCode is False")
        return True

    def help(self):
        self.parser.print_help()