import { Parser, Language, type Node } from 'web-tree-sitter';
import * as path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 解析后的命令结构
export interface ParsedCommand {
  name: string;        // 命令名，如 "git"
  subcommand?: string; // 子命令，如 "push"
  args: string[];      // 参数列表
  text: string;        // 原始命令文本
}

// 解析结果
export interface ParseResult {
  commands: ParsedCommand[];  // 所有解析出的命令
  success: boolean;
  error?: string;
}

// 单例解析器
let parserInstance: Parser | null = null;
let bashLanguage: Language | null = null;
let initPromise: Promise<void> | null = null;

/**
 * 获取 wasm 文件路径
 */
function getWasmPath(filename: string): string {
  // 从 node_modules 加载
  const nodeModulesPath = path.resolve(__dirname, '../../node_modules');

  if (filename === 'tree-sitter.wasm') {
    return path.join(nodeModulesPath, 'web-tree-sitter', filename);
  } else if (filename === 'tree-sitter-bash.wasm') {
    return path.join(nodeModulesPath, 'tree-sitter-bash', filename);
  }

  throw new Error(`Unknown wasm file: ${filename}`);
}

/**
 * 初始化解析器（懒加载，只初始化一次）
 */
async function initParser(): Promise<void> {
  if (parserInstance && bashLanguage) {
    return;
  }

  if (initPromise) {
    return initPromise;
  }

  initPromise = (async () => {
    try {
      // 初始化 tree-sitter
      await Parser.init({
        locateFile: (scriptName: string) => {
          return getWasmPath(scriptName);
        },
      });

      // 创建解析器实例
      parserInstance = new Parser();

      // 加载 bash 语言
      const bashWasmPath = getWasmPath('tree-sitter-bash.wasm');
      bashLanguage = await Language.load(bashWasmPath);
      parserInstance.setLanguage(bashLanguage);
    } catch (error) {
      initPromise = null;
      throw error;
    }
  })();

  return initPromise;
}

/**
 * 从语法树节点中提取命令信息
 */
function extractCommandFromNode(node: Node): ParsedCommand {
  const parts: string[] = [];

  for (let i = 0; i < node.childCount; i++) {
    const child = node.child(i);
    if (!child) continue;

    // 提取命令名和参数
    if (
      child.type === 'command_name' ||
      child.type === 'word' ||
      child.type === 'string' ||
      child.type === 'raw_string' ||
      child.type === 'concatenation' ||
      child.type === 'simple_expansion' ||
      child.type === 'expansion'
    ) {
      // 对于字符串类型，提取内部文本（去掉引号）
      if (child.type === 'string' || child.type === 'raw_string') {
        const text = child.text;
        if ((text.startsWith('"') && text.endsWith('"')) ||
            (text.startsWith("'") && text.endsWith("'"))) {
          parts.push(text.slice(1, -1));
        } else {
          parts.push(text);
        }
      } else {
        parts.push(child.text);
      }
    }
  }

  const name = parts[0] || '';
  // 找到第一个非 flag 参数作为子命令
  let subcommand: string | undefined;
  const args: string[] = [];

  for (let i = 1; i < parts.length; i++) {
    const part = parts[i];
    if (!subcommand && !part.startsWith('-')) {
      subcommand = part;
    } else {
      args.push(part);
    }
  }

  return {
    name,
    subcommand,
    args,
    text: node.text,
  };
}

/**
 * 递归查找所有命令节点
 */
function findCommandNodes(node: Node): Node[] {
  const commands: Node[] = [];

  if (node.type === 'command') {
    commands.push(node);
  }

  for (let i = 0; i < node.childCount; i++) {
    const child = node.child(i);
    if (child) {
      commands.push(...findCommandNodes(child));
    }
  }

  return commands;
}

/**
 * 解析 bash 命令字符串
 */
export async function parseBashCommand(command: string): Promise<ParseResult> {
  try {
    await initParser();

    if (!parserInstance) {
      return {
        commands: [],
        success: false,
        error: 'Parser not initialized',
      };
    }

    const tree = parserInstance.parse(command);
    if (!tree) {
      return {
        commands: [],
        success: false,
        error: 'Failed to parse command',
      };
    }

    const commandNodes = findCommandNodes(tree.rootNode);
    const commands = commandNodes.map(extractCommandFromNode);

    return {
      commands,
      success: true,
    };
  } catch (error) {
    return {
      commands: [],
      success: false,
      error: error instanceof Error ? error.message : String(error),
    };
  }
}

/**
 * 简单解析（用于降级，当 tree-sitter 不可用时）
 */
export function parseCommandSimple(command: string): ParsedCommand {
  const parts = command.trim().split(/\s+/);
  const name = parts[0] || '';

  let subcommand: string | undefined;
  const args: string[] = [];

  for (let i = 1; i < parts.length; i++) {
    const part = parts[i];
    if (!subcommand && !part.startsWith('-')) {
      subcommand = part;
    } else {
      args.push(part);
    }
  }

  return { name, subcommand, args, text: command };
}

/**
 * 检查解析器是否已初始化
 */
export function isParserInitialized(): boolean {
  return parserInstance !== null && bashLanguage !== null;
}
