#!/usr/bin/env python3
from __future__ import annotations

import argparse
import hashlib
import json
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

REPO = Path("/home/shire3d/ARMOR")
if str(REPO) not in sys.path:
    sys.path.insert(0, str(REPO))

from ai.brain_server import canonicalise_academy_answer
from services.design_academy_practice_service import practice_service

STATE = REPO / "data/academy/design_mastery/runtime/practice_state.json"
AUTO = REPO / "data/academy/design_mastery/runtime/autopilot_state.json"
SPRINT = REPO / "data/academy/design_mastery/runtime/commercial_design_sprint.json"
EVIDENCE_ROOT = Path("/SHiREVault/SHiREAcademy/Autopilot/Commercial")


def load(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8"))


def sha256(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def extract_response(payload: dict[str, Any], round_number: int) -> dict[str, Any]:
    for key in (
        "answer",
        "response",
        "canonical_answer",
        "canonical",
        "normalised_answer",
    ):
        value = payload.get(key)

        if isinstance(value, dict):
            return value

        if isinstance(value, str) and value.strip():
            try:
                parsed = json.loads(value)
                if isinstance(parsed, dict):
                    return parsed
            except json.JSONDecodeError:
                normalised = canonicalise_academy_answer(
                    value,
                    round_number,
                )
                return json.loads(normalised["canonical"])

    raw = payload.get("raw_answer")
    if isinstance(raw, str) and raw.strip():
        normalised = canonicalise_academy_answer(
            raw,
            round_number,
        )
        return json.loads(normalised["canonical"])

    raise RuntimeError(
        "Brain response did not contain a usable Academy answer"
    )


def main() -> int:
    parser = argparse.ArgumentParser(
        description="Generic uncounted SHiRE Academy qualification"
    )
    parser.add_argument("skill_id")
    parser.add_argument("round_number", type=int, choices=(1, 2, 3))
    args = parser.parse_args()

    state_before = sha256(STATE)
    practice = load(STATE)
    autopilot = load(AUTO)
    sprint = load(SPRINT)

    skill_id = args.skill_id
    round_number = args.round_number
    record = practice["skills"][skill_id]

    assert autopilot["current_skill"] == skill_id
    assert sprint["current_skill"] == skill_id
    assert record.get("forge_allowed") is False
    assert record.get("knowledge_certified") is False

    attempts_before = int(record.get("attempts") or 0)
    successes_before = int(record.get("successful_attempts") or 0)

    bundle = practice_service._lesson_bundle(skill_id)
    prompt = practice_service._practice_prompt(
        skill_id,
        bundle,
        round_number,
    )

    timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
    domain, name = skill_id.split(".", 1)
    evidence = (
        EVIDENCE_ROOT
        / sprint["sprint_id"]
        / domain
        / name
        / f"{timestamp}-UNCOUNTED-R{round_number}"
    )
    evidence.mkdir(parents=True, exist_ok=False)

    (evidence / "prompt.txt").write_text(
        prompt,
        encoding="utf-8",
    )
    (evidence / "pre_state.json").write_text(
        json.dumps({
            "skill_id": skill_id,
            "round": round_number,
            "attempts": attempts_before,
            "successful_attempts": successes_before,
            "knowledge_certified": record.get("knowledge_certified"),
            "forge_allowed": record.get("forge_allowed"),
            "practice_state_sha256": state_before,
        }, indent=2) + "\n",
        encoding="utf-8",
    )

    risk_mode = str(
        bundle["manifest"].get("risk_level") or "low"
    ).lower()

    payload = practice_service._ask_brain(
        prompt,
        risk_mode,
        round_number,
    )

    (evidence / "brain_payload.json").write_text(
        json.dumps(payload, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )

    response = extract_response(payload, round_number)

    guard_error = practice_service._response_contract_guard_error(
        bundle,
        response,
        round_number,
    )
    if guard_error:
        raise RuntimeError(guard_error)

    assessment = practice_service.evaluate_response(
        skill_id,
        bundle,
        response,
        round_number,
    )

    classification = (
        "UNCOUNTED_QUALIFICATION_PASS"
        if assessment["passed"]
        else "UNCOUNTED_QUALIFICATION_FAIL"
    )

    (evidence / "response.json").write_text(
        json.dumps(response, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )
    (evidence / "assessment.json").write_text(
        json.dumps(assessment, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )
    (evidence / "result.json").write_text(
        json.dumps({
            "classification": classification,
            "skill_id": skill_id,
            "round": round_number,
            "passed": assessment["passed"],
            "score_percent": assessment["score_percent"],
            "evidence": str(evidence),
            "counted_attempt_consumed": False,
            "forge_allowed": False,
        }, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
    )

    practice_after = load(STATE)
    record_after = practice_after["skills"][skill_id]

    assert sha256(STATE) == state_before
    assert int(record_after.get("attempts") or 0) == attempts_before
    assert int(record_after.get("successful_attempts") or 0) == successes_before
    assert record_after.get("knowledge_certified") is False
    assert record_after.get("forge_allowed") is False

    print(json.dumps({
        "ok": assessment["passed"],
        "classification": classification,
        "skill_id": skill_id,
        "round": round_number,
        "score_percent": assessment["score_percent"],
        "tests": assessment["tests"],
        "evidence": str(evidence),
        "counted_attempt_consumed": False,
        "practice_state_unchanged": True,
        "forge_allowed": False,
    }, indent=2, sort_keys=True))

    return 0 if assessment["passed"] else 2


if __name__ == "__main__":
    raise SystemExit(main())
