"""Unit tests for PyO3 checksum bindings (Phase 8: Checksum Spike).

Offline tests -- no network calls. Validates SPIKE-01 (correct results)
and SPIKE-03 (edge cases) for the standalone binding functions.
"""

from __future__ import annotations

import pytest
from opendeviationbar._core import (
    compute_sha256_hex,
    parse_checksum_file_content,
    verify_checksum_hex,
)


class TestComputeSha256Hex:
    """Tests for compute_sha256_hex() binding."""

    def test_known_hash(self) -> None:
        """SPIKE-01: Known SHA-256 hash of 'hello world'."""
        result = compute_sha256_hex(b"hello world")
        assert result == "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

    def test_empty(self) -> None:
        """SHA-256 of empty bytes is the well-known empty hash."""
        result = compute_sha256_hex(b"")
        assert result == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

    def test_large_data(self) -> None:
        """10 MB of null bytes produces a valid 64-char hex hash."""
        data = b"\x00" * (10 * 1024 * 1024)
        result = compute_sha256_hex(data)
        assert len(result) == 64
        assert all(c in "0123456789abcdef" for c in result)


class TestVerifyChecksumHex:
    """Tests for verify_checksum_hex() binding."""

    def test_match(self) -> None:
        """SPIKE-01: Matching hash returns dict with verified=True."""
        data = b"test data"
        expected = compute_sha256_hex(data)
        result = verify_checksum_hex(data, expected)
        assert isinstance(result, dict)
        assert result["verified"] is True
        assert result["skipped"] is False
        assert result["actual"] == expected
        assert result["expected"] == expected
        # Verify all 4 keys present
        for key in ("verified", "expected", "actual", "skipped"):
            assert key in result, f"missing key: {key}"

    def test_mismatch(self) -> None:
        """SPIKE-03: Mismatched hash raises RuntimeError with 'mismatch'."""
        data = b"test data"
        wrong_hash = "a" * 64
        with pytest.raises(RuntimeError, match="mismatch"):
            verify_checksum_hex(data, wrong_hash)

    def test_case_insensitive(self) -> None:
        """SPIKE-03: Uppercase expected hash still matches (case-insensitive)."""
        data = b"test data"
        expected_lower = compute_sha256_hex(data)
        expected_upper = expected_lower.upper()
        result = verify_checksum_hex(data, expected_upper)
        assert result["verified"] is True


class TestParseChecksumFileContent:
    """Tests for parse_checksum_file_content() binding."""

    def test_valid(self) -> None:
        """Standard Binance CHECKSUM format: hash + two spaces + filename."""
        content = "9572fa6526b5ba84dae0f66510c97b034f9da6b51c63ad1e0cffe528bfb65e40  BTCUSDT-aggTrades-2024-01-01.zip"
        result = parse_checksum_file_content(content)
        assert result == "9572fa6526b5ba84dae0f66510c97b034f9da6b51c63ad1e0cffe528bfb65e40"

    def test_with_newline(self) -> None:
        """Trailing newline is handled gracefully."""
        content = "9572fa6526b5ba84dae0f66510c97b034f9da6b51c63ad1e0cffe528bfb65e40  BTCUSDT-aggTrades-2024-01-01.zip\n"
        result = parse_checksum_file_content(content)
        assert result == "9572fa6526b5ba84dae0f66510c97b034f9da6b51c63ad1e0cffe528bfb65e40"

    def test_empty(self) -> None:
        """SPIKE-03: Empty content raises ValueError."""
        with pytest.raises(ValueError):
            parse_checksum_file_content("")

    def test_invalid_length(self) -> None:
        """SPIKE-03: Short hash raises ValueError."""
        with pytest.raises(ValueError):
            parse_checksum_file_content("abcdef  file.zip")

    def test_non_hex(self) -> None:
        """SPIKE-03: Non-hex characters in hash raise ValueError."""
        # 'g' is not a hex digit
        bad_hash = "g" + "0" * 63 + "  file.zip"
        with pytest.raises(ValueError):
            parse_checksum_file_content(bad_hash)
