#!/usr/bin/env python3
"""Focused regression tests for the standalone receipt-chain verifier."""

from __future__ import annotations

import contextlib
import hashlib
import io
import unittest
from pathlib import Path

import verify

REPO_ROOT = Path(__file__).resolve().parent
RECEIPTS = REPO_ROOT / "receipts"
HEAD = RECEIPTS / "receipt_04_hash_verification.json"


class ReceiptChainVerifierTests(unittest.TestCase):
    def test_valid_chain_walks_from_genesis_to_head(self) -> None:
        loaded = verify.load_receipts(RECEIPTS)
        result = verify.evaluate_loaded(loaded)
        self.assertEqual(result["mode"], "chain")
        self.assertEqual(len(result["records"]), 4)
        self.assertTrue(result["valid"])
        self.assertTrue(all(record["valid"] for record in result["records"]))
        self.assertTrue(all(record["link_valid"] for record in result["records"]))

    def test_single_file_behavior_remains_valid(self) -> None:
        loaded = verify.load_receipts(HEAD)
        result = verify.evaluate_loaded(loaded)
        self.assertEqual(result["mode"], "single")
        self.assertEqual(len(result["records"]), 1)
        self.assertIsNone(result["records"][0]["link_valid"])
        self.assertTrue(result["valid"])

    def test_expect_sha256_pins_chain_head_file(self) -> None:
        expected = hashlib.sha256(HEAD.read_bytes()).hexdigest()
        loaded = verify.load_receipts(RECEIPTS)
        result = verify.evaluate_loaded(loaded, expect_sha256=expected)
        self.assertTrue(result["expected_head_sha256_valid"])
        self.assertEqual(result["chain_head_file"], str(HEAD))
        self.assertTrue(result["valid"])

    def test_wrong_chain_head_pin_fails(self) -> None:
        loaded = verify.load_receipts(RECEIPTS)
        result = verify.evaluate_loaded(loaded, expect_sha256="0" * 64)
        self.assertFalse(result["expected_head_sha256_valid"])
        self.assertFalse(result["valid"])

    def test_mid_chain_tamper_breaks_signature_and_downstream_link(self) -> None:
        loaded = verify.load_receipts(RECEIPTS)
        result = verify.evaluate_loaded(loaded, tamper=True)
        self.assertFalse(result["records"][1]["signature_valid"])
        self.assertFalse(result["records"][1]["entry_hash_valid"])
        self.assertFalse(result["records"][2]["link_valid"])
        self.assertFalse(result["valid"])

    def test_tamper_cli_returns_failure(self) -> None:
        with contextlib.redirect_stdout(io.StringIO()):
            exit_code = verify.run(RECEIPTS, tamper=True)
        self.assertEqual(exit_code, 1)


if __name__ == "__main__":
    unittest.main()
