"""
Data types for the Cross-Model Verification Kernel.
These classes define the core data structures used throughout the system.
"""

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any


class NodeStatus(Enum):
    """Status of a node in the Graph of Truth."""

    PENDING = "pending"
    VERIFIED = "verified"
    FAILED = "failed"
    IN_PROGRESS = "in_progress"


class VerificationOutcome(Enum):
    """Result of verification process."""

    PASS = "pass"
    FAIL = "fail"
    UNCERTAIN = "uncertain"


@dataclass
class VerificationResult:
    """Result of a verification check by the Adversary."""

    outcome: VerificationOutcome
    confidence: float  # 0.0 to 1.0
    critical_issues: list[str] = field(default_factory=list)
    logic_flaws: list[str] = field(default_factory=list)
    missing_edge_cases: list[str] = field(default_factory=list)
    test_coverage_gaps: list[str] = field(default_factory=list)
    minor_issues: list[str] = field(default_factory=list)
    reasoning: str = ""
    timestamp: datetime = field(default_factory=datetime.now)
    # Prosecutor Mode: Generated hostile test cases
    hostile_tests: list[str] = field(default_factory=list)
    hostile_test_results: dict[str, Any] = field(default_factory=dict)

    def has_critical_issues(self) -> bool:
        """Check if there are any critical issues."""
        return len(self.critical_issues) > 0 or len(self.logic_flaws) > 0


@dataclass
class GenerationResult:
    """Result of code generation by the Generator."""

    solution: str
    explanation: str
    test_cases: str
    edge_cases: list[str] = field(default_factory=list)
    metadata: dict[str, Any] = field(default_factory=dict)
    timestamp: datetime = field(default_factory=datetime.now)


@dataclass
class Node:
    """A node in the Graph of Truth representing a piece of verified knowledge."""

    id: str
    content: str
    status: NodeStatus
    verification_results: list[VerificationResult] = field(default_factory=list)
    metadata: dict[str, Any] = field(default_factory=dict)
    created_at: datetime = field(default_factory=datetime.now)
    updated_at: datetime = field(default_factory=datetime.now)
    parent_id: str | None = None
    children_ids: list[str] = field(default_factory=list)

    def is_verified(self) -> bool:
        """Check if this node has been successfully verified."""
        return self.status == NodeStatus.VERIFIED


@dataclass
class ExecutionTrace:
    """Record of a single execution attempt in the verification loop."""

    step_id: int
    code_generated: str
    verifier_feedback: str
    status: str  # "success" or "failed"
    strategy_used: str | None = None  # e.g. "recursive", "numpy", "brute_force"


@dataclass
class NodeState:
    """Tracks the state of a single problem-solving node."""

    input_query: str
    current_code: str | None = None
    status: str = "pending"  # pending, verified, rejected
    history: list[ExecutionTrace] = field(default_factory=list)
    forbidden_strategies: list[str] = field(default_factory=list)

    @property
    def fail_count(self) -> int:
        """Count the number of failed attempts."""
        return len([t for t in self.history if t.status == "failed"])


@dataclass
class KernelState:
    """Current state of the kernel execution."""

    task_description: str
    current_loop: int
    max_loops: int
    current_solution: GenerationResult | None = None
    verification_history: list[VerificationResult] = field(default_factory=list)
    graph_nodes: list[Node] = field(default_factory=list)
    is_complete: bool = False
    final_result: str | None = None
    metadata: dict[str, Any] = field(default_factory=dict)
