from __future__ import annotations

import argparse
import json
import pathlib
import sys
import tempfile
from typing import Any, Callable

ROOT = pathlib.Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)); sys.path.insert(0, str(ROOT / "src"))


def result(name: str, passed: bool, detail: Any) -> dict[str, Any]: return {"probe": name, "passed": bool(passed), "detail": detail}
def expect_block(fn: Callable[[], Any]) -> bool:
    try: fn()
    except Exception: return True
    return False


def probe_action_schema() -> dict[str, Any]:
    from reliability_core.models import AgentAction
    allowed = {"get_case", "save_review_draft"}
    invalid = [{"tool":"get_case","arguments":{"case_id":"c"},"request_id":123,"idempotency_key":None},{"tool":"get_case","arguments":{"case_id":"c"},"request_id":"","idempotency_key":None},{"tool":"save_review_draft","arguments":{"case_id":"c","draft_version":1},"request_id":"r","idempotency_key":123},{"tool":"save_review_draft","arguments":{"case_id":"c","draft_version":1},"request_id":"r"}]
    blocked = [expect_block(lambda payload=p: AgentAction.from_payload(payload, allowed)) for p in invalid]
    return result("action_schema", all(blocked), {"blocked": blocked})


def probe_retry_flag() -> dict[str, Any]:
    from reliability_core.harness import valid_documents
    from reliability_core.policy import ExternalApprovalService
    from reliability_core.runtime import WorkflowRuntime
    from reliability_core.tools import FaultInjector
    flags = {"checkpoint":True,"retry":False,"idempotency":True,"state_policy":True,"external_approval":True,"independent_evaluation":True}
    runtime = WorkflowRuntime(run_id="probe-retry-off", faults=FaultInjector(7,{"apply_mock_update":"transient_before_commit"}), capabilities=flags)
    waiting = runtime.execute("case-retry-off", valid_documents()); ExternalApprovalService(runtime.store,runtime.policy).decide(waiting["pending_approval_id"],"external-reviewer")
    try:
        final = runtime.continue_ready("case-retry-off", valid_documents(), 2); ok = not final.get("backoff_history") and final["state"] != "COMPLETED"; detail = {"state":final["state"],"backoff":final.get("backoff_history")}
    except Exception as exc: ok = True; detail = {"blocked":type(exc).__name__}
    return result("retry_flag_effective", ok, detail)


def probe_external_approval_flag() -> dict[str, Any]:
    from reliability_core.harness import valid_documents
    from reliability_core.runtime import WorkflowRuntime
    flags = {"checkpoint":True,"retry":True,"idempotency":True,"state_policy":True,"external_approval":False,"independent_evaluation":True}
    runtime=WorkflowRuntime(run_id="probe-approval-off",capabilities=flags); final=runtime.execute("case-approval-off",valid_documents()); approvals=runtime.store.rows_for_case("approvals","case-approval-off","probe-approval-off")
    return result("external_approval_flag_effective",len(approvals)==0 and not final.get("pending_approval_id"),{"state":final["state"],"approval_count":len(approvals)})


def probe_budget_preflight() -> dict[str, Any]:
    from reliability_core.harness import valid_documents
    from reliability_core.models import Budget
    from reliability_core.runtime import WorkflowRuntime
    runtime=WorkflowRuntime(run_id="probe-budget-zero",budget=Budget(max_steps=0)); blocked=expect_block(lambda:runtime.execute("case-budget-zero",valid_documents())); state=runtime.store.state("case-budget-zero","probe-budget-zero"); transitions=runtime.store.rows_for_case("transitions","case-budget-zero","probe-budget-zero"); effects=runtime.store.rows_for_case("effects","case-budget-zero","probe-budget-zero")
    return result("budget_preflight",blocked and state=="RECEIVED" and not transitions and not effects,{"state":state,"transitions":len(transitions),"effects":len(effects)})


def probe_checkpoint_scope() -> dict[str, Any]:
    from reliability_core.harness import valid_documents
    from reliability_core.runtime import WorkflowRuntime
    from reliability_core.storage import Store
    store=Store(); a=WorkflowRuntime(store=store,run_id="run-a"); a.execute("same-case",valid_documents(),stop_after_ready=True); store.create_case("same-case","READY_FOR_REVIEW",run_id="run-b"); store.log("run-b","same-case","COMPLETED",{"foreign":True},"foreign-request","get_case"); store.add_effect("same-case","save_review_draft","foreign-effect","hash",{"ok":True},"run-b"); checkpoint=a.checkpoint("same-case"); serialized=json.dumps(checkpoint,sort_keys=True); clean="foreign-request" not in serialized and "foreign-effect" not in serialized
    return result("checkpoint_case_run_scope",clean,{"foreign_data_present":not clean})


def probe_traceability_mutant() -> dict[str, Any]:
    from scripts.build_evidence import build_semantic_traceability
    with tempfile.TemporaryDirectory() as directory:
        root=pathlib.Path(directory); (root/"module.py").write_text("def real_symbol():\n    return True\n",encoding="utf-8"); mappings={"REQ-X":{"code_locations":["module.py:999-1000"],"test_ids":["TEST-X"],"symbols":["missing_symbol"],"assertion_ids":["ASSERT-X"]}}; raw=[{"test_id":"TEST-X","run_id":"run-x","passed":True,"assertion":"unrelated pass","assertion_id":"ASSERT-OTHER"}]
        try: records=build_semantic_traceability(mappings,raw,root); passed=bool(records) and records[0].get("status")!="PASS"; detail=records[0] if records else {"empty":True}
        except Exception as exc: passed=True; detail={"blocked":type(exc).__name__}
    return result("traceability_mutant",passed,detail)


def main() -> int:
    argparse.ArgumentParser().parse_args(); rows=[]
    for probe in [probe_action_schema,probe_retry_flag,probe_external_approval_flag,probe_budget_preflight,probe_checkpoint_scope,probe_traceability_mutant]:
        try: rows.append(probe())
        except Exception as exc: rows.append(result(probe.__name__,False,{"error":type(exc).__name__,"message":str(exc)}))
    payload={"passed":all(row["passed"] for row in rows),"probe_count":len(rows),"results":rows}; print(json.dumps(payload,ensure_ascii=False,indent=2,sort_keys=True)); return 0 if payload["passed"] else 1


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