/**
 * Parser Registry
 *
 * Factory for creating language-specific parsers based on file extension.
 */

import path from 'path';
import { BaseLanguageParser, type ParserConstructor } from './base-parser.js';
import { TypeScriptParser } from './typescript-parser.js';
import type { ParserInfo, SupportedLanguage } from '../types.js';

/**
 * Parser Registry
 *
 * Manages registered parsers and routes files to the appropriate parser.
 */
export class ParserRegistry {
  private static parsers: Map<string, ParserConstructor> = new Map();
  private static parserInfo: Map<ParserConstructor, ParserInfo> = new Map();

  /**
   * Register a parser class for its supported extensions
   */
  static register(
    ParserClass: ParserConstructor,
    info: { name: string; language: SupportedLanguage }
  ): void {
    // Create a temporary instance to get extensions
    const tempParser = new ParserClass('', '');
    const extensions = tempParser.getSupportedExtensions();

    // Store parser info
    ParserRegistry.parserInfo.set(ParserClass, {
      ...info,
      extensions,
    });

    // Register for each extension
    for (const ext of extensions) {
      const normalizedExt = ext.toLowerCase();
      ParserRegistry.parsers.set(normalizedExt, ParserClass);
    }
  }

  /**
   * Get a parser instance for a file
   */
  static getParser(filePath: string, repoRoot?: string): BaseLanguageParser | null {
    const ext = path.extname(filePath).toLowerCase();
    const ParserClass = ParserRegistry.parsers.get(ext);

    if (!ParserClass) {
      return null;
    }

    return new ParserClass(filePath, repoRoot);
  }

  /**
   * Check if a file type is supported
   */
  static isSupported(filePath: string): boolean {
    const ext = path.extname(filePath).toLowerCase();
    return ParserRegistry.parsers.has(ext);
  }

  /**
   * Get all supported extensions
   */
  static getAllExtensions(): string[] {
    return Array.from(ParserRegistry.parsers.keys());
  }

  /**
   * List all registered parsers
   */
  static listParsers(): ParserInfo[] {
    return Array.from(ParserRegistry.parserInfo.values());
  }

  /**
   * Get parser info for an extension
   */
  static getParserInfo(extension: string): ParserInfo | null {
    const ParserClass = ParserRegistry.parsers.get(extension.toLowerCase());
    if (!ParserClass) return null;
    return ParserRegistry.parserInfo.get(ParserClass) ?? null;
  }

  /**
   * Clear all registered parsers (useful for testing)
   */
  static clear(): void {
    ParserRegistry.parsers.clear();
    ParserRegistry.parserInfo.clear();
  }
}

// Auto-register built-in parsers
ParserRegistry.register(TypeScriptParser, {
  name: 'TypeScriptParser',
  language: 'typescript',
});

/**
 * Get a parser for a file (convenience function)
 */
export function getParser(filePath: string, repoRoot?: string): BaseLanguageParser | null {
  return ParserRegistry.getParser(filePath, repoRoot);
}

/**
 * Check if a file type is supported (convenience function)
 */
export function isSupported(filePath: string): boolean {
  return ParserRegistry.isSupported(filePath);
}

/**
 * Get all supported extensions (convenience function)
 */
export function getSupportedExtensions(): string[] {
  return ParserRegistry.getAllExtensions();
}
