# -*- coding: utf-8 -*-
"""Regression: self-key is always FAIL (ANCHOR-5).

Fixtures used: 1 (task-2644 self-key FAIL), 3 (envelope mismatch FAIL).
Verifies that actual_owner_key == executor_key always results in FAIL.
"""
from __future__ import annotations

import json
from pathlib import Path

import pytest

from utils.callback_authority_validator import (
    FAIL,
    PASS,
    STATE_NON_AUTHORITATIVE_SELF_COLLECTOR,
    validate_authority,
)
from utils.callback_registration import (
    ANU_KEY,
    STATE_NON_AUTHORITATIVE_SELF_COLLECTOR as REG_STATE_NON_AUTH,
    VERDICT_FAIL,
    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
    return (
        json.loads((base / "evidence.json").read_text()),
        json.loads((base / "expected.json").read_text()),
    )


class TestFixture01TaskSelfKeyFail:
    """fixture_01: task-2644 9CAB9D33 dev1 self-key → FAIL."""

    def test_validate_authority_self_key_fail(self):
        evidence, expected = load_fixture("fixture_01_task_2644_self_key_fail")
        verdict = validate_authority(
            envelope_collector_key=evidence["envelope"]["collector_key"],
            actual_owner_key=evidence["observed_owner_key"],
            executor_key=evidence["executor_key"],
        )
        assert verdict.verdict == FAIL, f"expected FAIL, got {verdict.verdict!r}"
        assert verdict.state == STATE_NON_AUTHORITATIVE_SELF_COLLECTOR
        assert verdict.authority_marker == expected["authority_marker"]

    def test_validate_authority_self_key_state(self):
        """State enum must match fixture expected."""
        evidence, expected = load_fixture("fixture_01_task_2644_self_key_fail")
        verdict = validate_authority(
            envelope_collector_key=evidence["envelope"]["collector_key"],
            actual_owner_key=evidence["observed_owner_key"],
            executor_key=evidence["executor_key"],
        )
        assert verdict.state == expected["state"]

    def test_verify_actual_owner_self_key_fails(self):
        """verify_actual_owner with self-key observed → FAIL."""
        rr = register_callback(
            kind="normal",
            task_id="task-2644",
            executor_key=EXECUTOR_KEY,
            owner_key=ANU_KEY,
            chat_id="chat-dev1",
            prompt="task_id=task-2644\nowner_key=c119085addb0f8b7\n",
            at="10m",
            dispatch_path=True,
            direct_cron_path=False,
            require_envelope=False,
        )
        # Simulate: actual owner resolved to self-key despite ANU in envelope
        verified = verify_actual_owner(
            registration_result=rr,
            observed_owner_key=EXECUTOR_KEY,  # self-key!
            observed_chat_id="chat-dev1",
            observed_role="SELF",
        )
        assert verified.verdict == VERDICT_FAIL
        # ANCHOR-1: must contain ENVELOPE_ACTUAL_MISMATCH reason
        reasons_text = " ".join(verified.reasons)
        assert "ENVELOPE_ACTUAL_MISMATCH" in reasons_text or "MISMATCH" in reasons_text


class TestSelfKeyAlwaysFailClosed:
    """Any self-key registration attempt must fail regardless of envelope."""

    @pytest.mark.parametrize("envelope_key", [ANU_KEY, EXECUTOR_KEY, "arbitrary-key"])
    def test_self_key_always_fails(self, envelope_key: str):
        """actual == executor always → NON_AUTHORITATIVE_SELF_COLLECTOR."""
        verdict = validate_authority(
            envelope_collector_key=envelope_key,
            actual_owner_key=EXECUTOR_KEY,
            executor_key=EXECUTOR_KEY,
        )
        assert verdict.verdict == FAIL
        assert verdict.state == STATE_NON_AUTHORITATIVE_SELF_COLLECTOR

    def test_self_key_registration_fails(self):
        """register_callback with self-key owner → FAIL."""
        rr = register_callback(
            kind="normal",
            task_id="test-self-key",
            executor_key=EXECUTOR_KEY,
            owner_key=EXECUTOR_KEY,  # self-key
            chat_id="chat-x",
            prompt="task_id=test-self-key\nowner_key=c38fb9955616e24d\n",
            at="10m",
            dispatch_path=True,
            direct_cron_path=False,
            require_envelope=False,
        )
        assert rr.verdict == VERDICT_FAIL
