"""Evidence types for Global Compiler."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from lattice.core.types.proposal import Proposal


@dataclass(frozen=True)
class CandidatePattern:
    """A candidate pattern from Global Compiler Phase 1.

    >>> cp = CandidatePattern(
    ...     pattern="Prefer explicit type hints",
    ...     source_projects=["project-a", "project-b"],
    ...     description="Pattern appears in multiple projects",
    ... )
    >>> len(cp.source_projects)
    2
    """

    pattern: str
    source_projects: list[str]
    description: str = ""


@dataclass(frozen=True)
class Evidence:
    """Evidence for a global rule.

    >>> ev = Evidence(
    ...     id=1,
    ...     source_project="/Users/tefx/Projects/my-app",
    ...     source_session_id="session-abc",
    ...     pattern="Prefer TDD",
    ...     summary="Test-first approach in 5 sessions",
    ... )
    >>> ev.source_project
    '/Users/tefx/Projects/my-app'
    """

    id: int
    source_project: str
    source_session_id: str
    pattern: str
    summary: str
    source_rule_file: str | None = None
    original_snippet: str | None = None
    extracted_at: str = ""  # Caller must provide timestamp (Shell layer responsibility)
    compiler_trace: str | None = None
    confidence: float = 0.0


@dataclass(frozen=True)
class PromoteAction:
    """Action to promote a project rule to global.

    >>> action = PromoteAction(
    ...     source_project="project-a",
    ...     source_rule_file="conventions.md",
    ...     target_global_file="preferences.md",
    ...     rule_content="Always cite sources.",
    ... )
    >>> action.source_project
    'project-a'
    """

    source_project: str
    source_rule_file: str
    target_global_file: str
    rule_content: str
    marked_promoted: bool = False


@dataclass(frozen=True)
class SecretSpan:
    """Span of detected secret in text.

    >>> span = SecretSpan(start=10, end=30, pattern="api_key")
    >>> span.start
    10
    """

    start: int
    end: int
    pattern: str


@dataclass(frozen=True)
class CotPhases:
    """Structured Chain-of-Thought phases from Compiler.

    >>> phases = CotPhases(
    ...     triage="Scanned sessions, found key signals...",
    ...     cross_ref="Compared patterns across sessions...",
    ...     synthesis="Generated 2 proposals...",
    ...     review="Reviewed 5 existing rules...",
    ... )
    >>> phases.triage
    'Scanned sessions, found key signals...'
    """

    triage: str
    cross_ref: str
    synthesis: str
    review: str


@dataclass(frozen=True)
class CompilerOutput:
    """Output from a Compiler run.

    >>> output = CompilerOutput(
    ...     proposals=[],
    ...     cot_phases=CotPhases(
    ...         triage="...",
    ...         cross_ref="...",
    ...         synthesis="...",
    ...         review="...",
    ...     ),
    ...     trace_path="drift/traces/20260217.trace.md",
    ... )
    >>> output.proposals
    []
    """

    proposals: list["Proposal"]
    cot_phases: CotPhases
    trace_path: str
    sessions_processed: int = 0
    rules_added: int = 0
    rules_merged: int = 0
    rules_removed: int = 0


@dataclass(frozen=True)
class ProjectRegistration:
    """A registered project in projects.toml.

    >>> reg = ProjectRegistration(
    ...     path="/Users/tefx/Projects/my-app",
    ...     name="my-app",
    ...     registered_at="2026-02-17T10:00:00Z",
    ... )
    >>> reg.name
    'my-app'
    """

    path: str
    name: str
    registered_at: str
    exclude_from_global: bool = False


@dataclass(frozen=True)
class ExcludedProject:
    """A project excluded from lazy initialization.

    >>> ex = ExcludedProject(
    ...     path="/Users/tefx/Projects/test-fixtures",
    ...     excluded_at="2026-02-21T10:00:00Z",
    ...     reason="Read-only test fixtures",
    ... )
    >>> ex.path
    '/Users/tefx/Projects/test-fixtures'
    >>> ex.reason
    'Read-only test fixtures'
    """

    path: str
    excluded_at: str
    reason: str = ""
