# -*- coding: utf-8 -*-
"""Regression: dispatch_path and direct_cron_path both use same helper (ANCHOR-2).

Fixtures used: 2 (ANU key PASS), 7 (dispatch_path PASS), 8 (direct_cron PASS).
Verifies:
- dispatch_path=True + ANU owner → DISPATCH_SUBMITTED_UNVERIFIED then OWNER_KEY_VERIFIED
- direct_cron_path=True + ANU owner → same path
- both False → REGISTRATION_HELPER_BYPASSED
"""
from __future__ import annotations

import json
from pathlib import Path

import pytest

from utils.callback_registration import (
    ANU_KEY,
    HELPER_SCHEMA,
    STATE_DISPATCH_SUBMITTED_UNVERIFIED,
    STATE_OWNER_KEY_VERIFIED,
    STATE_REGISTRATION_HELPER_BYPASSED,
    VERDICT_FAIL,
    VERDICT_PASS,
    register_callback,
    verify_actual_owner,
)

FIXTURE_DIR = Path(__file__).parent.parent.parent / "fixtures" / "callback_authority_gate"
EXECUTOR_KEY = "c38fb9955616e24d"


def load_fixture(name: str) -> tuple[dict, dict]:
    base = FIXTURE_DIR / name
    evidence = json.loads((base / "evidence.json").read_text())
    expected = json.loads((base / "expected.json").read_text())
    return evidence, expected


class TestDispatchPathWithHelper:
    """fixture_07: dispatch_path=True + ANU owner → PASS via helper."""

    def test_register_gives_dispatch_submitted_unverified(self):
        evidence, expected = load_fixture("fixture_07_dispatch_path_with_helper_pass")
        ri = evidence["registration_input"]
        rr = register_callback(
            kind=ri["kind"],
            task_id=ri["task_id"],
            executor_key=ri["executor_key"],
            owner_key=ri["owner_key"],
            chat_id=ri["chat_id"],
            prompt=ri["prompt"],
            at=ri["at"],
            dispatch_path=ri["dispatch_path"],
            direct_cron_path=ri["direct_cron_path"],
            require_envelope=ri.get("require_envelope", True),
        )
        assert rr.state == STATE_DISPATCH_SUBMITTED_UNVERIFIED, (
            f"expected DISPATCH_SUBMITTED_UNVERIFIED, got {rr.state!r}"
        )
        assert rr.schema == HELPER_SCHEMA

    def test_verify_gives_owner_key_verified(self):
        evidence, expected = load_fixture("fixture_07_dispatch_path_with_helper_pass")
        ri = evidence["registration_input"]
        vi = evidence["verify_input"]
        rr = register_callback(
            kind=ri["kind"],
            task_id=ri["task_id"],
            executor_key=ri["executor_key"],
            owner_key=ri["owner_key"],
            chat_id=ri["chat_id"],
            prompt=ri["prompt"],
            at=ri["at"],
            dispatch_path=ri["dispatch_path"],
            direct_cron_path=ri["direct_cron_path"],
            require_envelope=ri.get("require_envelope", True),
        )
        verified = verify_actual_owner(
            registration_result=rr,
            observed_owner_key=vi["observed_owner_key"],
            observed_chat_id=vi["observed_chat_id"],
            observed_role=vi["observed_role"],
        )
        assert verified.state == expected["state_after_verify"]
        assert verified.verdict == expected["verdict"]
        assert verified.authority_marker == expected["authority_marker"]


class TestDirectCronPathWithHelper:
    """fixture_08: direct_cron_path=True + ANU owner → PASS (회장 정정)."""

    def test_register_gives_dispatch_submitted_unverified(self):
        evidence, expected = load_fixture(
            "fixture_08_direct_cron_with_helper_actual_owner_verified_pass"
        )
        ri = evidence["registration_input"]
        rr = register_callback(
            kind=ri["kind"],
            task_id=ri["task_id"],
            executor_key=ri["executor_key"],
            owner_key=ri["owner_key"],
            chat_id=ri["chat_id"],
            prompt=ri["prompt"],
            at=ri["at"],
            dispatch_path=ri["dispatch_path"],
            direct_cron_path=ri["direct_cron_path"],
            require_envelope=ri.get("require_envelope", True),
        )
        assert rr.state == STATE_DISPATCH_SUBMITTED_UNVERIFIED

    def test_verify_gives_owner_key_verified(self):
        evidence, expected = load_fixture(
            "fixture_08_direct_cron_with_helper_actual_owner_verified_pass"
        )
        ri = evidence["registration_input"]
        vi = evidence["verify_input"]
        rr = register_callback(
            kind=ri["kind"],
            task_id=ri["task_id"],
            executor_key=ri["executor_key"],
            owner_key=ri["owner_key"],
            chat_id=ri["chat_id"],
            prompt=ri["prompt"],
            at=ri["at"],
            dispatch_path=ri["dispatch_path"],
            direct_cron_path=ri["direct_cron_path"],
            require_envelope=ri.get("require_envelope", True),
        )
        verified = verify_actual_owner(
            registration_result=rr,
            observed_owner_key=vi["observed_owner_key"],
            observed_chat_id=vi["observed_chat_id"],
            observed_role=vi["observed_role"],
        )
        assert verified.state == expected["state_after_verify"]
        assert verified.verdict == expected["verdict"]


class TestBothPathsFalseBypassed:
    """fixture_06: both paths False → REGISTRATION_HELPER_BYPASSED."""

    def test_bypassed_when_both_false(self):
        evidence, expected = load_fixture(
            "fixture_06_direct_cron_no_helper_raw_self_key"
        )
        ri = evidence["registration_input"]
        rr = register_callback(
            kind=ri["kind"],
            task_id=ri["task_id"],
            executor_key=ri["executor_key"],
            owner_key=ri["owner_key"],
            chat_id=ri["chat_id"],
            prompt=ri["prompt"],
            at=ri["at"],
            dispatch_path=ri["dispatch_path"],
            direct_cron_path=ri["direct_cron_path"],
        )
        assert rr.state == STATE_REGISTRATION_HELPER_BYPASSED
        assert rr.verdict == VERDICT_FAIL

    def test_anu_owner_also_bypassed_when_paths_both_false(self):
        """Even with ANU owner, both=False bypasses helper."""
        rr = register_callback(
            kind="normal",
            task_id="test-bypass-anu",
            executor_key=EXECUTOR_KEY,
            owner_key=ANU_KEY,
            chat_id="chat-x",
            prompt="task_id=test-bypass-anu\n",
            at="10m",
            dispatch_path=False,
            direct_cron_path=False,
        )
        assert rr.state == STATE_REGISTRATION_HELPER_BYPASSED
        assert rr.verdict == VERDICT_FAIL


class TestANUKeyPassFromFixture2:
    """fixture_02: ANU key PASS — verify register + verify_actual_owner."""

    def test_anu_key_fully_verified(self):
        """Simulate fixture_02 via API: register then verify."""
        rr = register_callback(
            kind="normal",
            task_id="task-2645",
            executor_key="dev2-executor-key",
            owner_key=ANU_KEY,
            chat_id="chat-dev2",
            prompt="task_id=task-2645\nowner_key=c119085addb0f8b7\n",
            at="10m",
            dispatch_path=True,
            direct_cron_path=False,
            require_envelope=False,
        )
        assert rr.state == STATE_DISPATCH_SUBMITTED_UNVERIFIED
        verified = verify_actual_owner(
            registration_result=rr,
            observed_owner_key=ANU_KEY,
            observed_chat_id="chat-dev2",
            observed_role="ANU",
        )
        assert verified.state == STATE_OWNER_KEY_VERIFIED
        assert verified.verdict == VERDICT_PASS
