"""Service for linting user code across 10 programming languages."""
import sys
import os
import tempfile
import subprocess
from typing import Dict, Any
from src.core.registry import registry


class CodeLinter:
    """Lints user code for syntax and style issues for 10 languages."""

    def lint(self, language: str, code: str) -> Dict[str, Any]:
        config = registry.get_config(language)
        if not config:
            return {
                "language": language,
                "exit_code": 1,
                "stdout": "",
                "stderr": f"Language '{language}' is not supported.",
            }

        lang_key = registry.canonical_name(language)
        ext = config.get("ext", ".txt")

        with tempfile.TemporaryDirectory() as tmpdir:
            if lang_key == "java":
                temp_file_name = "Main.java"
            elif lang_key == "cpp":
                temp_file_name = "main.cpp"
            elif lang_key == "rust":
                temp_file_name = "main.rs"
            elif lang_key == "csharp":
                temp_file_name = "Program.cs"
            else:
                temp_file_name = f"main{ext}"

            temp_path = os.path.join(tmpdir, temp_file_name)
            with open(temp_path, "w", encoding="utf-8") as f:
                f.write(code)

            try:
                if lang_key == "python":
                    cmd = [sys.executable, "-m", "flake8", temp_path]
                    result = subprocess.run(cmd, capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "javascript":
                    result = subprocess.run(["node", "--check", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "typescript":
                    result = subprocess.run(["npx", "tsc", "--noEmit", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "lua":
                    result = subprocess.run(["luac", "-p", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "go":
                    result = subprocess.run(["go", "vet", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "cpp":
                    result = subprocess.run(["g++", "-fsyntax-only", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "rust":
                    result = subprocess.run(["rustc", "--emit=metadata", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "java":
                    result = subprocess.run(["javac", temp_path], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                elif lang_key == "html":
                    result = subprocess.run(["python3", "-c", f"import html.parser; html.parser.HTMLParser().feed(open('{temp_path}').read())"], capture_output=True, text=True, cwd=tmpdir, timeout=15)
                else:
                    lint_cmd = config["lint"]
                    result = subprocess.run(f"{lint_cmd} {temp_path}", shell=True, capture_output=True, text=True, cwd=tmpdir, timeout=15)

                return {
                    "language": language,
                    "exit_code": result.returncode,
                    "stdout": result.stdout,
                    "stderr": result.stderr,
                }
            except FileNotFoundError as fnf:
                return {
                    "language": language,
                    "exit_code": 0,
                    "stdout": f"✓ Syntax check skipped (linter tool not installed for {language}).",
                    "stderr": "",
                }
            except subprocess.TimeoutExpired:
                return {
                    "language": language,
                    "exit_code": 124,
                    "stdout": "",
                    "stderr": "Linting timed out.",
                }
            except Exception as e:
                return {
                    "language": language,
                    "exit_code": 1,
                    "stdout": "",
                    "stderr": str(e),
                }


linter = CodeLinter()
