from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field


class StructuredError(BaseModel):
    error_type: str
    message: str | None = None
    file: str | None = None
    line: int | None = None
    test_name: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class MemoryHit(BaseModel):
    task_id: str | None = None
    score: float = 0.0
    summary: str
    source: str = "task"
    metadata: dict[str, Any] = Field(default_factory=dict)


class ValidationCheckResult(BaseModel):
    name: str
    success: bool
    command: str | None = None
    exit_code: int | None = None
    stdout: str = ""
    stderr: str = ""
    structured_errors: list[StructuredError] = Field(default_factory=list)


class ValidationSummary(BaseModel):
    valid: bool = True
    failed_checks: list[str] = Field(default_factory=list)
    checks: list[ValidationCheckResult] = Field(default_factory=list)


class CriticResult(BaseModel):
    result: str = "pass"
    issues: list[str] = Field(default_factory=list)
    repair_guidance: list[str] = Field(default_factory=list)


class EvaluationSummary(BaseModel):
    passed: bool = True
    issues: list[str] = Field(default_factory=list)


class FocusIssue(BaseModel):
    issue_type: str = "model_inferred"
    path: str
    title: str
    line: int | None = None
    evidence: str | None = None
    acceptance_check: str | None = None
    metadata: dict[str, str] = Field(default_factory=dict)


class FocusIssueInventory(BaseModel):
    focus_paths: list[str] = Field(default_factory=list)
    issues: list[FocusIssue] = Field(default_factory=list)
    acceptance_checks: list[str] = Field(default_factory=list)


class FocusReviewResult(BaseModel):
    passed: bool = True
    unresolved_issues: list[str] = Field(default_factory=list)
    resolved_issues: list[str] = Field(default_factory=list)
    notes: str | None = None


class SubtaskRecord(BaseModel):
    task_id: str
    parent_task: str | None = None
    description: str
    tool: str
    expected_output: str
    status: str = "pending"


class WorkspaceSnapshotRecord(BaseModel):
    task_id: str
    source_repo_path: str
    workspace_path: str
    strategy: str
