"""Terminal provider failure matrix for disposable Telegram publication."""

from __future__ import annotations

from dataclasses import replace
from pathlib import Path


from gateway.config import PlatformConfig

from gateway.platforms.nutrition_weekly_operations import Topic59DayCardProjector
from gateway.platforms.nutrition_weekly_operations_models import Topic59DayState
from scripts.nutricoach_v140_authority_fixture import CANDIDATE
from scripts.nutricoach_v140_fake_telegram import (
    FakeTelegramEngine,
    ProviderMode,
    fake_bot,
)
from scripts.nutricoach_v140_telegram_facade import (
    DisposableWeeklyTelegramAdapter,
    Topic59TransportFacade,
)
from scripts.nutricoach_v140_runtime import JsonValue
from scripts.nutricoach_v140_topic59_fixture import create_topic59_fixture


class TerminalProviderRetryError(RuntimeError):
    """A terminal provider result incorrectly caused a replacement call."""


def _terminal_edit_class(
    mode: ProviderMode, ledger_text: str,
) -> tuple[int, int, int]:
    expected = {
        ProviderMode.KNOWN_FAILURE: ("failed", "rejected"),
        ProviderMode.TIMEOUT: ("unknown", "timeout"),
        ProviderMode.UNKNOWN: ("unknown", "connection_lost"),
        ProviderMode.DELIVERED: ("sent_audited", ""),
    }
    vectors = {
        ProviderMode.KNOWN_FAILURE: (1, 0, 0),
        ProviderMode.TIMEOUT: (0, 1, 0),
        ProviderMode.UNKNOWN: (0, 0, 1),
        ProviderMode.DELIVERED: (0, 0, 0),
    }
    state, reason = expected[mode]
    passed = (
        f'"state":"{state}"' in ledger_text
        and f'"provider_reason":"{reason}"' in ledger_text
    )
    vector = vectors[mode]
    flag = int(passed)
    return flag * vector[0], flag * vector[1], flag * vector[2]


async def run_failure_matrix(root: Path) -> dict[str, JsonValue]:
    """Prove terminal provider outcomes never cause a replacement call."""
    terminal = 0
    known_failed = 0
    timeout_unknown = 0
    ambiguous_unknown = 0
    modes: tuple[ProviderMode, ...] = (
        ProviderMode.KNOWN_FAILURE,
        ProviderMode.TIMEOUT,
        ProviderMode.UNKNOWN,
    )
    for mode in modes:
        fixture = create_topic59_fixture(root / str(mode))
        config = PlatformConfig(
            enabled=True, token="disabled", extra=fixture.authority.extra,
        )
        missed = fixture.request(Topic59DayState.MISSED)
        send_engine = FakeTelegramEngine()
        send_engine.set_mode(mode)
        send_transport = Topic59TransportFacade(DisposableWeeklyTelegramAdapter(
            config, fake_bot(send_engine), CANDIDATE,
        ))
        send_projector = Topic59DayCardProjector(root / f"send-{mode}.jsonl")
        _ = await send_projector.publish(missed, send_transport)
        _ = await send_projector.publish(missed, send_transport)
        if send_engine.attempts != 1 or send_engine.provider_calls() != 0:
            raise TerminalProviderRetryError
        terminal += 1

        edit_engine = FakeTelegramEngine()
        edit_transport = Topic59TransportFacade(DisposableWeeklyTelegramAdapter(
            config, fake_bot(edit_engine), CANDIDATE,
        ))
        edit_projector = Topic59DayCardProjector(root / f"edit-{mode}.jsonl")
        _ = await edit_projector.publish(missed, edit_transport)
        edit_engine.set_mode(mode)
        late = fixture.request(Topic59DayState.LATE_SUBMITTED)
        _ = await edit_projector.publish(late, edit_transport)
        _ = await edit_projector.publish(late, edit_transport)
        if edit_engine.attempts != 2 or edit_engine.provider_calls() != 1:
            raise TerminalProviderRetryError
        ledger_text = (root / f"edit-{mode}.jsonl").read_text(encoding="utf-8")
        classified = _terminal_edit_class(mode, ledger_text)
        known_failed += classified[0]
        timeout_unknown += classified[1]
        ambiguous_unknown += classified[2]
        terminal += 1
    authority_fixture = create_topic59_fixture(root / "authority-denials")
    config = PlatformConfig(
        enabled=True, token="disabled", extra=authority_fixture.authority.extra,
    )
    missed = authority_fixture.request(Topic59DayState.MISSED)
    late = authority_fixture.request(Topic59DayState.LATE_SUBMITTED)
    authority_engine = FakeTelegramEngine()
    authority_transport = Topic59TransportFacade(DisposableWeeklyTelegramAdapter(
        config, fake_bot(authority_engine), CANDIDATE,
    ))
    authority_projector = Topic59DayCardProjector(root / "stale-authority.jsonl")
    stale_authority = replace(
        missed, runtime=replace(missed.runtime, candidate_digest="0" * 64),
    )
    stale_consent = replace(
        missed, runtime=replace(missed.runtime, consent_granted=False),
    )
    _ = await authority_projector.publish(stale_authority, authority_transport)
    _ = await authority_projector.publish(stale_consent, authority_transport)
    if authority_engine.attempts:
        raise TerminalProviderRetryError

    corrupt_path = root / "corrupt-ledger.jsonl"
    corrupt_engine = FakeTelegramEngine()
    corrupt_transport = Topic59TransportFacade(DisposableWeeklyTelegramAdapter(
        config, fake_bot(corrupt_engine), CANDIDATE,
    ))
    corrupt_projector = Topic59DayCardProjector(corrupt_path)
    _ = await corrupt_projector.publish(missed, corrupt_transport)
    _ = corrupt_path.write_text("{", encoding="utf-8")
    _ = await corrupt_projector.publish(late, corrupt_transport)
    if corrupt_engine.attempts != 1:
        raise TerminalProviderRetryError
    return {
        "terminal_provider_classes": terminal, "unauthorized_provider_calls": 0,
        "stale_authority_denials": 1, "stale_consent_denials": 1,
        "corrupt_ledger_denials": 1,
        "known_edit_failed_rejected": known_failed,
        "timeout_edit_unknown": timeout_unknown,
        "ambiguous_edit_unknown": ambiguous_unknown,
    }
