"""DetectCompletionService - Detect step completion via dual mechanism.

Contract: CNT-T2-SVC-005
Traceability: UC-005, BR-002
"""

from dataclasses import dataclass, field
from pathlib import Path


@dataclass(frozen=True, slots=True)
class CompletionResult:
    """Result of completion detection."""

    stdout_markers_found: bool
    files_verified: bool
    is_complete: bool
    missing_files: list[str] = field(default_factory=list)

    def __str__(self) -> str:
        """Return human-readable completion status."""
        if self.is_complete:
            return "Step completed successfully"
        issues = []
        if not self.stdout_markers_found:
            issues.append("completion markers not found in output")
        if not self.files_verified:
            issues.append(f"missing files: {', '.join(self.missing_files)}")
        return f"Step incomplete: {'; '.join(issues)}"


class DetectCompletionService:
    """Service for detecting step completion.

    Uses dual detection mechanism:
    1. Console markers in stdout
    2. File verification (checking for _index.yaml)
    """

    COMPLETION_MARKERS = [
        "Step completed",
        "Phase complete",
        "_index.yaml created",
        "All files generated",
    ]

    def detect(
        self,
        stdout: str,
        expected_files: list[str],
        project_path: Path | None = None,
    ) -> CompletionResult:
        """Detect if step execution completed successfully.

        Args:
            stdout: Standard output from Claude Code execution
            expected_files: List of expected output files or patterns
            project_path: Optional project path for file verification

        Returns:
            CompletionResult with detection outcome
        """
        # Check stdout for completion markers
        stdout_markers_found = any(
            marker.lower() in stdout.lower() for marker in self.COMPLETION_MARKERS
        )

        # Verify files exist
        files_verified = True
        missing_files: list[str] = []

        if project_path:
            for file_pattern in expected_files:
                path = Path(file_pattern)
                check_path = path if path.is_absolute() else project_path / file_pattern

                # Handle glob patterns
                if "*" in str(check_path):
                    parent = check_path.parent
                    pattern = check_path.name
                    if parent.exists():
                        matches = list(parent.glob(pattern))
                        if not matches:
                            files_verified = False
                            missing_files.append(file_pattern)
                    else:
                        files_verified = False
                        missing_files.append(file_pattern)
                elif not check_path.exists():
                    files_verified = False
                    missing_files.append(file_pattern)

        # Complete if either mechanism confirms
        is_complete = stdout_markers_found or files_verified

        return CompletionResult(
            stdout_markers_found=stdout_markers_found,
            files_verified=files_verified,
            is_complete=is_complete,
            missing_files=missing_files,
        )
