#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
waveform_trace CLI 入口
用于 PyInstaller 打包成独立可执行文件

使用方式:
    waveform_trace --verilog <path> --vcd <path> --sim-output <text> [--trace-level <int>] [--output-format text|json]
"""

import sys
import os
import builtins

# Monkey-patch open 函数，强制使用 UTF-8 编码（解决 pyverilog 读取中文注释的问题）
_original_open = builtins.open
def _utf8_open(file, mode='r', *args, **kwargs):
    if 'b' not in mode and 'encoding' not in kwargs:
        kwargs['encoding'] = 'utf-8'
        kwargs.setdefault('errors', 'replace')
    return _original_open(file, mode, *args, **kwargs)
builtins.open = _utf8_open

if sys.platform == 'win32':
    sys.stdout.reconfigure(encoding='utf-8', errors='replace')
    sys.stderr.reconfigure(encoding='utf-8', errors='replace')

import argparse
import json

# 添加当前目录到路径（打包后需要）
if getattr(sys, 'frozen', False):
    # 如果是打包后的可执行文件
    application_path = os.path.dirname(sys.executable)
else:
    # 如果是直接运行的脚本
    application_path = os.path.dirname(os.path.abspath(__file__))

sys.path.insert(0, application_path)

from waveform_trace_tool import WaveformTracer


def main():
    parser = argparse.ArgumentParser(
        description='Verilog 波形追踪工具 - 通过 AST + BFS 追踪信号依赖，定位代码问题',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
示例:
    waveform_trace --verilog src/counter.v --vcd output/wave.vcd --sim-output "Mismatches: 3"
    waveform_trace --verilog src/counter.v --vcd output/wave.vcd --sim-output "Mismatches: 3" --trace-level 3
    waveform_trace --verilog src/counter.v --vcd output/wave.vcd --sim-output "Mismatches: 3" --output-format json
        '''
    )

    parser.add_argument(
        '--verilog',
        required=True,
        help='Verilog 源文件路径'
    )
    parser.add_argument(
        '--vcd',
        required=True,
        help='VCD 波形文件路径'
    )
    parser.add_argument(
        '--sim-output',
        required=True,
        help='仿真工具的输出字符串（必须包含 mismatch 信息）'
    )
    parser.add_argument(
        '--trace-level',
        type=int,
        default=2,
        help='BFS 回溯层数，默认 2，建议 2-5'
    )
    parser.add_argument(
        '--output-format',
        choices=['text', 'json'],
        default='text',
        help='输出格式：text（默认）或 json'
    )

    args = parser.parse_args()

    try:
        # 验证文件存在
        if not os.path.exists(args.verilog):
            raise FileNotFoundError(f"Verilog 文件不存在: {args.verilog}")
        if not os.path.exists(args.vcd):
            raise FileNotFoundError(f"VCD 文件不存在: {args.vcd}")

        # 验证 trace_level
        if args.trace_level < 1:
            raise ValueError("trace-level 必须大于等于 1")

        # 创建追踪器并执行
        tracer = WaveformTracer(args.verilog, args.vcd)
        result = tracer.waveform_trace_tool(args.sim_output, args.trace_level)

        # 输出结果
        if args.output_format == 'json':
            output = {
                'success': True,
                'result': result,
                'verilog_path': args.verilog,
                'vcd_path': args.vcd,
                'trace_level': args.trace_level
            }
            print(json.dumps(output, ensure_ascii=False, indent=2))
        else:
            print(result)

    except FileNotFoundError as e:
        if args.output_format == 'json':
            print(json.dumps({
                'success': False,
                'error': str(e),
                'error_type': 'FileNotFoundError'
            }, ensure_ascii=False))
        else:
            print(f'[Error] {e}', file=sys.stderr)
        sys.exit(1)

    except ValueError as e:
        if args.output_format == 'json':
            print(json.dumps({
                'success': False,
                'error': str(e),
                'error_type': 'ValueError'
            }, ensure_ascii=False))
        else:
            print(f'[Error] {e}', file=sys.stderr)
        sys.exit(1)

    except Exception as e:
        if args.output_format == 'json':
            print(json.dumps({
                'success': False,
                'error': str(e),
                'error_type': type(e).__name__
            }, ensure_ascii=False))
        else:
            print(f'[Error] {e}', file=sys.stderr)
        sys.exit(1)


if __name__ == '__main__':
    main()
