import libcst
from pydantic import StringConstraints, field_validator
from pydantic.dataclasses import dataclass
from typing_extensions import Annotated


@dataclass(frozen=True)
class CodeAndExplanation:
    cst_module: libcst.Module
    explanation: Annotated[str, StringConstraints(min_length=1)]

    @field_validator("cst_module")
    def validate_cst_module(cls, v):
        if not isinstance(v, libcst.Module):
            raise ValueError("cst_module must be an instance of libcst.Module")
        try:
            # Unparse the CST module to get the source code
            source_code = v.code
            # Compile the source code to check for syntax errors
            compile(source_code, "<string>", "exec")
        except Exception as e:
            raise ValueError(f"Invalid cst_module, compilation error: {e}")
        return v


@dataclass(frozen=True)
class CodeExplanationAndID:
    cst_module: libcst.Module
    explanation: str
    id: str

    @field_validator("cst_module")
    def validate_cst_module(cls, v):
        if not isinstance(v, libcst.Module):
            raise ValueError("cst_module must be an instance of libcst.Module")
        try:
            # Unparse the CST module to get the source code
            source_code = v.code
            # Compile the source code to check for syntax errors
            compile(source_code, "<string>", "exec")
        except Exception as e:
            raise ValueError(f"Invalid cst_module, compilation error: {e}")
        return v
