"""Error injection utilities for AI regression testing."""

from pathlib import Path
from typing import Literal

ErrorType = Literal[
    "function_name_typo",
    "missing_include",
    "missing_semicolon",
    "undefined_variable",
    "type_mismatch",
    "wrong_parameter_count",
    "bracket_mismatch",
    "comment_syntax_error",
    "duplicate_definition",
    "case_sensitive_error",
]


class ErrorInjector:
    """Inject compilation errors into STM32 project for testing."""

    def __init__(self, project_root: Path):
        """
        Initialize error injector.

        Args:
            project_root: Root directory of the STM32 project
        """
        self.project_root = project_root
        self.main_c = project_root / "USER" / "main.c"
        self.original_content: str | None = None

    def inject_error(self, error_type: ErrorType) -> str:
        """
        Inject specific error type into main.c.

        Args:
            error_type: Type of error to inject

        Returns:
            Expected error message substring

        Raises:
            ValueError: If error_type is not supported
        """
        if not self.main_c.exists():
            raise FileNotFoundError(f"main.c not found: {self.main_c}")

        # Backup original content
        self.original_content = self.main_c.read_text(encoding="utf-8", errors="ignore")
        content = self.original_content

        # Inject error based on type
        if error_type == "function_name_typo":
            # delay_ms → Delay_ms (函數名稱拼寫錯誤)
            content = content.replace("delay_ms(", "Delay_ms(")
            expected_error = "'Delay_ms' undeclared"

        elif error_type == "missing_include":
            # 移除 #include "delay.h"
            content = content.replace('#include "delay.h"', "")
            expected_error = "'delay_ms' undeclared"

        elif error_type == "missing_semicolon":
            # 移除第一個 delay_ms 後的分號
            content = content.replace("delay_ms(500);", "delay_ms(500)", 1)
            expected_error = "expected ';'"

        elif error_type == "undefined_variable":
            # 使用未定義的變數
            content = content.replace(
                "while(1)",
                "uint8_t undefined_var = some_undefined_var;\n    while(1)",
            )
            expected_error = "'some_undefined_var' undeclared"

        elif error_type == "type_mismatch":
            # HAL_Delay → 傳入錯誤型別參數
            if "HAL_Delay(" in content:
                content = content.replace("HAL_Delay(500);", 'HAL_Delay("500");')
            else:
                # 如果沒有 HAL_Delay，改用 delay_ms
                content = content.replace("delay_ms(500);", 'delay_ms("500");')
            expected_error = "conversion"

        elif error_type == "wrong_parameter_count":
            # 參數數量錯誤
            content = content.replace("delay_ms(500);", "delay_ms(500, 100);")
            expected_error = "too many arguments"

        elif error_type == "bracket_mismatch":
            # 括號不匹配
            content = content.replace("while(1) {", "while(1) {{")
            expected_error = "expected"

        elif error_type == "comment_syntax_error":
            # 註解語法錯誤 - 未結束的多行註解
            content = content.replace("int main(void)", "/* Unclosed comment\nint main(void)")
            expected_error = "unterminated comment"

        elif error_type == "duplicate_definition":
            # 重複定義變數
            content = content.replace(
                "int main(void)\n{",
                "int main(void)\n{\n    int i = 0;\n    int i = 1;",
            )
            expected_error = "redefinition"

        elif error_type == "case_sensitive_error":
            # GPIO_PIN_RESET → gpio_pin_reset
            content = content.replace("GPIO_PIN_RESET", "gpio_pin_reset")
            expected_error = "'gpio_pin_reset' undeclared"

        else:
            raise ValueError(f"Unsupported error type: {error_type}")

        # Write modified content
        self.main_c.write_text(content, encoding="utf-8")

        return expected_error

    def restore(self):
        """Restore original main.c content."""
        if self.original_content is not None:
            self.main_c.write_text(self.original_content, encoding="utf-8")
            self.original_content = None

    def get_error_description(self, error_type: ErrorType) -> str:
        """Get human-readable description of error type."""
        descriptions = {
            "function_name_typo": "函數名稱拼寫錯誤（大小寫）",
            "missing_include": "缺少標頭檔案引入",
            "missing_semicolon": "缺少分號",
            "undefined_variable": "使用未定義的變數",
            "type_mismatch": "型別不匹配",
            "wrong_parameter_count": "函數參數數量錯誤",
            "bracket_mismatch": "括號不匹配",
            "comment_syntax_error": "註解語法錯誤",
            "duplicate_definition": "重複定義變數",
            "case_sensitive_error": "大小寫敏感錯誤（常數名稱）",
        }
        return descriptions.get(error_type, "未知錯誤類型")
