"""Language detection and parser dispatch."""

from pathlib import Path

from codectx.parser.types import ParseResult

SUPPORTED_EXTENSIONS: dict[str, str] = {
    # Core (tree-sitter accelerated)
    ".go":   "go",
    ".py":   "python",
    ".pyw":  "python",
    ".js":   "javascript",
    ".jsx":  "javascript",
    ".mjs":  "javascript",
    ".cjs":  "javascript",
    ".ts":   "typescript",
    ".tsx":  "typescript",
    ".mts":  "typescript",
    ".cts":  "typescript",
    ".java": "java",
    # Tier 1
    ".rs":    "rust",
    ".cs":    "csharp",
    ".rb":    "ruby",
    ".sql":   "sql",
    ".kt":    "kotlin",
    ".kts":   "kotlin",
    ".scala": "scala",
    ".sc":    "scala",
    ".sbt":   "scala",
    # Tier 2
    ".sh":    "bash",
    ".bash":  "bash",
    ".zsh":   "bash",
    ".fish":  "bash",
    ".lua":   "lua",
    ".pl":    "perl",
    ".pm":    "perl",
    ".r":     "r",
    ".R":     "r",
    # Tier 3 — markup & config
    ".html":  "html",
    ".htm":   "html",
    ".css":   "css",
    ".scss":  "css",
    ".sass":  "css",
    ".md":    "markdown",
    ".markdown": "markdown",
    ".json":  "json",
    ".xml":   "xml",
    ".xsd":   "xml",
    ".xsl":   "xml",
    ".xslt":  "xml",
    ".svg":   "xml",
    ".yml":   "yaml",
    ".yaml":  "yaml",
    ".toml":  "toml",
    ".hcl":   "hcl",
    ".tf":    "hcl",
    ".tfvars": "hcl",
    ".properties": "properties",
}

# Dockerfile has no extension — matched by filename below.
_FILENAME_MAP: dict[str, str] = {
    "Dockerfile": "dockerfile",
    "dockerfile": "dockerfile",
}


def detect_language(file_path: str) -> str:
    p = Path(file_path)
    by_name = _FILENAME_MAP.get(p.name)
    if by_name:
        return by_name
    return SUPPORTED_EXTENSIONS.get(p.suffix.lower(), "unknown")


# Lazy parser dispatch: (module_path, function_name)
# Parsers are only imported when first needed for a given language.
_PARSER_DISPATCH: dict[str, tuple[str, str]] = {
    "python":     ("codectx.parser.python_parser",     "parse_python"),
    "go":         ("codectx.parser.go_parser",          "parse_go"),
    "javascript": ("codectx.parser.javascript_parser",  "parse_javascript"),
    "typescript": ("codectx.parser.javascript_parser",  "parse_javascript"),
    "java":       ("codectx.parser.java_parser",        "parse_java"),
    "rust":       ("codectx.parser.rust_parser",        "parse_rust"),
    "csharp":     ("codectx.parser.csharp_parser",      "parse_csharp"),
    "ruby":       ("codectx.parser.ruby_parser",        "parse_ruby"),
    "sql":        ("codectx.parser.sql_parser",         "parse_sql"),
    "kotlin":     ("codectx.parser.kotlin_parser",      "parse_kotlin"),
    "scala":      ("codectx.parser.scala_parser",       "parse_scala"),
    "bash":       ("codectx.parser.bash_parser",        "parse_bash"),
    "lua":        ("codectx.parser.lua_parser",         "parse_lua"),
    "perl":       ("codectx.parser.perl_parser",        "parse_perl"),
    "r":          ("codectx.parser.r_parser",           "parse_r"),
    "html":       ("codectx.parser.html_parser",        "parse_html"),
    "css":        ("codectx.parser.css_parser",         "parse_css"),
    "markdown":   ("codectx.parser.markdown_parser",    "parse_markdown"),
    "json":       ("codectx.parser.json_parser",        "parse_json"),
    "xml":        ("codectx.parser.xml_parser",         "parse_xml"),
    "yaml":       ("codectx.parser.yaml_parser",        "parse_yaml"),
    "toml":       ("codectx.parser.toml_parser",        "parse_toml"),
    "hcl":        ("codectx.parser.hcl_parser",         "parse_hcl"),
    "properties": ("codectx.parser.properties_parser",  "parse_properties"),
    "dockerfile": ("codectx.parser.dockerfile_parser",  "parse_dockerfile"),
}

# Cache loaded parser functions to avoid repeated importlib calls
_loaded_parsers: dict[str, object] = {}


def parse_file(file_path: str, content: str) -> ParseResult:
    """Dispatch to the appropriate language parser (lazy-loaded on demand)."""
    import importlib

    language = detect_language(file_path)
    dispatch = _PARSER_DISPATCH.get(language)
    if dispatch is None:
        return ParseResult(file_path=file_path, language=language)

    module_path, func_name = dispatch
    if language not in _loaded_parsers:
        mod = importlib.import_module(module_path)
        _loaded_parsers[language] = getattr(mod, func_name)

    parser_fn = _loaded_parsers[language]
    return parser_fn(file_path, content)
