# -*- coding: utf-8 -*-
"""
TEITAN SELF-REPAIR - FUNCTIONAL DIAGNOSTIC ADAPTER
Converts an InternalFunctionalAssessor evaluation failure into a canonical
MissionFailureEvent, IncidentRecord, and EvidenceBundle so it can be directly
consumed by RootCauseAnalyzer without fabricating false external missions.
"""
from __future__ import annotations

import os
from typing import Any, Dict, Optional, Tuple

from app.remediation.self_repair.functional_assessor import (
    FunctionalAssessmentStatus,
    FunctionalEvaluationResult,
)
from app.remediation.self_repair.schemas import (
    EvidenceBundle,
    IncidentFailureType,
    IncidentRecord,
    MissionFailureEvent,
    _new_id,
    _utc_iso,
)


class FunctionalDiagnosticAdapter:
    """
    Transforms internal functional evaluation failures into canonical
    IncidentRecord and EvidenceBundle for root-cause diagnosis.
    """

    @classmethod
    def failure_result_to_incident_and_evidence(
        cls,
        eval_result: FunctionalEvaluationResult,
        workspace_root: str,
    ) -> Tuple[MissionFailureEvent, IncidentRecord, EvidenceBundle]:
        """
        Builds a canonical failure event without external mission fabrication.
        """
        assert eval_result.status in (
            FunctionalAssessmentStatus.FAIL,
            FunctionalAssessmentStatus.BLOCKED,
        ), f"Cannot convert non-failing result status {eval_result.status}"

        diag_id = _new_id("diag_inc")
        now_ts = _utc_iso()
        target_rel = eval_result.target_file_rel
        target_abs = os.path.join(workspace_root, target_rel)

        symptom = (
            f"Internal functional contract failure: {eval_result.contract_id} "
            f"on component {eval_result.component_name}. Error: {eval_result.assertion_error}"
        )

        err_ctx = {
            "component_id": eval_result.component_name,
            "contract_id": eval_result.contract_id,
            "target_file": target_rel,
            "file_sha256": eval_result.file_sha256,
            "assertion_error": eval_result.assertion_error,
            "duration_ms": eval_result.duration_ms,
        }

        exec_history = [
            {
                "stage": "functional_assessment",
                "component": eval_result.component_name,
                "target": target_rel,
                "status": "FAIL",
                "error": eval_result.assertion_error,
            }
        ]

        tracebacks = [eval_result.stack_trace] if eval_result.stack_trace else []
        logs = [f"Functional contract execution output:\n{eval_result.stdout}"] if eval_result.stdout else []

        event = MissionFailureEvent(
            mission_id=f"m_internal_eval_{eval_result.contract_id}",
            instance_id="inst_internal_assessor",
            task_id=f"task_eval_{eval_result.contract_id}",
            timestamp=now_ts,
            workspace_root=workspace_root,
            failure_stage=eval_result.component_name,
            observed_symptom=symptom,
            exception_type="AssertionError",
            exception_message=eval_result.assertion_error or symptom,
            source_component=eval_result.component_name,
            execution_history=exec_history,
            verification_result={"target": target_rel, "status": "FAIL", "error": eval_result.assertion_error},
            evidence_locations={"target_file": target_rel},
            mission_status="FAILED",
            error_context=err_ctx,
            target_file=target_rel,
            target_files=[target_rel],
            source_files=[target_rel],
        )

        incident = IncidentRecord(
            incident_id=diag_id,
            mission_id=event.mission_id,
            failure_type=IncidentFailureType.FAILED_TEST,
            observed_symptom=symptom,
            source_component=eval_result.component_name,
            timestamp=now_ts,
            initial_evidence=err_ctx,
        )

        source_excerpts = []
        if os.path.isfile(target_abs):
            try:
                with open(target_abs, "r", encoding="utf-8", errors="replace") as f:
                    lines = f.readlines()
                source_excerpts.append({
                    "file_path": target_rel,
                    "line_count": len(lines),
                    "head_excerpt": "".join(lines[:30]),
                    "tail_excerpt": "".join(lines[-30:]),
                    "sha256": eval_result.file_sha256,
                })
            except Exception:
                pass

        evidence = EvidenceBundle(
            incident_id=diag_id,
            logs=logs,
            tracebacks=tracebacks,
            action_history=exec_history,
            target_file=target_rel,
            source_files=[target_rel],
            source_excerpts=source_excerpts,
            relevant_config={"assessor_version": "alpha_1.0"},
        )

        return event, incident, evidence

