/**
 * 波形追踪工具
 * 调用 PyInstaller 打包的 waveform_trace 可执行文件
 */
import { spawn } from 'child_process';
import * as path from 'path';
import * as fs from 'fs';
import * as vscode from 'vscode';

/**
 * 波形追踪参数
 */
export interface WaveformTraceArgs {
  /** Verilog 源文件路径（相对于项目根目录） */
  verilogPath: string;
  /** VCD 波形文件路径（相对于项目根目录） */
  vcdPath: string;
  /** 仿真工具的输出字符串（包含 mismatch 信息） */
  simOutput: string;
  /** BFS 回溯层数，默认 2 */
  traceLevel?: number;
}

/**
 * 执行波形追踪
 * @param args 追踪参数
 * @param context 执行上下文
 * @returns 追踪结果字符串
 */
export async function executeWaveformTrace(
  args: WaveformTraceArgs,
  context: { extensionPath: string }
): Promise<string> {
  // 获取可执行文件路径
  const tracerPath = getWaveformTracerPath(context.extensionPath);

  // 检查可执行文件是否存在
  if (!fs.existsSync(tracerPath)) {
    throw new Error(
      `waveform_trace 工具未安装: ${tracerPath}\n` +
      '请确保插件包含 tools/waveform_trace/bin/ 目录'
    );
  }

  // 获取工作区路径
  const workspaceFolders = vscode.workspace.workspaceFolders;
  if (!workspaceFolders || workspaceFolders.length === 0) {
    throw new Error('请先打开一个工作区');
  }
  const workspacePath = workspaceFolders[0].uri.fsPath;

  // 解析路径（支持相对路径）
  const verilogAbsPath = path.isAbsolute(args.verilogPath)
    ? args.verilogPath
    : path.join(workspacePath, args.verilogPath);
  const vcdAbsPath = path.isAbsolute(args.vcdPath)
    ? args.vcdPath
    : path.join(workspacePath, args.vcdPath);

  // 验证文件存在
  if (!fs.existsSync(verilogAbsPath)) {
    throw new Error(`Verilog 文件不存在: ${args.verilogPath}`);
  }
  if (!fs.existsSync(vcdAbsPath)) {
    throw new Error(`VCD 文件不存在: ${args.vcdPath}`);
  }

  // 调用可执行文件
  return new Promise((resolve, reject) => {
    const child = spawn(tracerPath, [
      '--verilog', verilogAbsPath,
      '--vcd', vcdAbsPath,
      '--sim-output', args.simOutput,
      '--trace-level', String(args.traceLevel || 2),
      '--output-format', 'text'
    ], {
      windowsHide: true,
      cwd: workspacePath,
      shell: false
    });

    let stdout = '';
    let stderr = '';

    child.stdout.on('data', (data: Buffer) => {
      stdout += data.toString();
    });

    child.stderr.on('data', (data: Buffer) => {
      stderr += data.toString();
    });

    child.on('close', (code: number | null) => {
      if (code === 0) {
        resolve(stdout);
      } else {
        reject(new Error(
          `waveform_trace 执行失败 (code=${code}):\n${stderr || stdout}`
        ));
      }
    });

    child.on('error', (error: Error) => {
      reject(new Error(`waveform_trace 启动失败: ${error.message}`));
    });
  });
}

/**
 * 获取 waveform_trace 可执行文件路径
 */
function getWaveformTracerPath(extensionPath: string): string {
  const platform = process.platform;
  let binName = 'waveform_trace';

  if (platform === 'win32') {
    binName = 'waveform_trace.exe';
  }

  return path.join(extensionPath, 'tools', 'waveform_trace', 'bin', binName);
}

/**
 * 检查 waveform_trace 工具是否可用
 */
export function checkWaveformTraceAvailable(extensionPath: string): {
  available: boolean;
  message: string;
  path?: string;
} {
  const tracerPath = getWaveformTracerPath(extensionPath);

  if (fs.existsSync(tracerPath)) {
    return {
      available: true,
      message: 'waveform_trace 工具可用',
      path: tracerPath
    };
  } else {
    return {
      available: false,
      message: `waveform_trace 工具未找到: ${tracerPath}`
    };
  }
}
