"""Tests for killswitch — verifies emergency purge destroys all sensitive data."""

from __future__ import annotations

import hashlib
from pathlib import Path

import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import (
    Encoding,
    NoEncryption,
    PrivateFormat,
    PublicFormat,
)


@pytest.fixture()
def populated_soosef(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
    """Create a populated ~/.soosef directory with identity, chain, attestations, etc."""
    import soosef.paths as paths

    data_dir = tmp_path / ".soosef"
    data_dir.mkdir()
    monkeypatch.setattr(paths, "BASE_DIR", data_dir)

    # Create identity
    identity_dir = data_dir / "identity"
    identity_dir.mkdir()
    key = Ed25519PrivateKey.generate()
    priv_pem = key.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption())
    (identity_dir / "private.pem").write_bytes(priv_pem)
    pub_pem = key.public_key().public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
    (identity_dir / "public.pem").write_bytes(pub_pem)

    # Create channel key
    stegasoo_dir = data_dir / "stegasoo"
    stegasoo_dir.mkdir()
    (stegasoo_dir / "channel.key").write_text("test-channel-key")

    # Create chain data
    from soosef.federation.chain import ChainStore

    chain_dir = data_dir / "chain"
    store = ChainStore(chain_dir)
    for i in range(3):
        store.append(hashlib.sha256(f"c-{i}".encode()).digest(), "test/plain", key)

    # Create attestation dir with a dummy file
    att_dir = data_dir / "attestations"
    att_dir.mkdir()
    (att_dir / "log.bin").write_bytes(b"dummy attestation data")

    # Create other dirs
    (data_dir / "auth").mkdir()
    (data_dir / "auth" / "soosef.db").write_bytes(b"dummy db")
    (data_dir / "temp").mkdir()
    (data_dir / "temp" / "file.tmp").write_bytes(b"tmp")
    (data_dir / "instance").mkdir()
    (data_dir / "instance" / ".secret_key").write_bytes(b"secret")
    (data_dir / "config.json").write_text("{}")

    return data_dir


def test_purge_all_destroys_chain_data(populated_soosef: Path):
    """CRITICAL: execute_purge(ALL) must destroy chain directory."""
    from soosef.fieldkit.killswitch import PurgeScope, execute_purge

    chain_dir = populated_soosef / "chain"
    assert chain_dir.exists()
    assert (chain_dir / "chain.bin").exists()

    result = execute_purge(PurgeScope.ALL, reason="test")

    assert not chain_dir.exists(), "Chain directory must be destroyed by killswitch"
    assert "destroy_chain_data" in result.steps_completed


def test_purge_all_destroys_identity(populated_soosef: Path):
    """execute_purge(ALL) must destroy identity keys."""
    from soosef.fieldkit.killswitch import PurgeScope, execute_purge

    assert (populated_soosef / "identity" / "private.pem").exists()

    result = execute_purge(PurgeScope.ALL, reason="test")

    assert not (populated_soosef / "identity").exists()
    assert "destroy_identity_keys" in result.steps_completed


def test_purge_all_destroys_attestation_log(populated_soosef: Path):
    """execute_purge(ALL) must destroy the Verisoo attestation log."""
    from soosef.fieldkit.killswitch import PurgeScope, execute_purge

    result = execute_purge(PurgeScope.ALL, reason="test")

    assert not (populated_soosef / "attestations").exists()
    assert "destroy_attestation_log" in result.steps_completed


def test_purge_keys_only_preserves_chain(populated_soosef: Path):
    """KEYS_ONLY purge destroys keys but preserves chain and attestation data."""
    from soosef.fieldkit.killswitch import PurgeScope, execute_purge

    result = execute_purge(PurgeScope.KEYS_ONLY, reason="test")

    # Keys gone
    assert not (populated_soosef / "identity").exists()
    assert "destroy_identity_keys" in result.steps_completed

    # Chain and attestations preserved (KEYS_ONLY doesn't touch data)
    assert (populated_soosef / "chain" / "chain.bin").exists()
    assert (populated_soosef / "attestations" / "log.bin").exists()


def test_purge_reports_all_steps(populated_soosef: Path):
    """execute_purge(ALL) reports all expected steps including chain."""
    from soosef.fieldkit.killswitch import PurgeScope, execute_purge

    result = execute_purge(PurgeScope.ALL, reason="test")

    expected_steps = [
        "destroy_identity_keys",
        "destroy_channel_key",
        "destroy_flask_secret",
        "destroy_auth_db",
        "destroy_attestation_log",
        "destroy_chain_data",
        "destroy_temp_files",
        "destroy_config",
    ]
    for step in expected_steps:
        assert step in result.steps_completed, f"Missing purge step: {step}"
