"""Tests for certisigma.hash utilities."""
import hashlib
import os
import tempfile

import pytest

from certisigma.hash import hash_file, hash_bytes


class TestHashBytes:
    def test_empty(self):
        expected = hashlib.sha256(b"").hexdigest()
        assert hash_bytes(b"") == expected

    def test_known_value(self):
        data = b"hello world"
        expected = hashlib.sha256(data).hexdigest()
        assert hash_bytes(data) == expected

    def test_bytearray(self):
        data = bytearray(b"test data")
        expected = hashlib.sha256(data).hexdigest()
        assert hash_bytes(data) == expected

    def test_memoryview(self):
        data = b"memoryview test"
        expected = hashlib.sha256(data).hexdigest()
        assert hash_bytes(memoryview(data)) == expected

    def test_returns_64_hex(self):
        result = hash_bytes(b"anything")
        assert len(result) == 64
        assert all(c in "0123456789abcdef" for c in result)

    def test_rejects_string(self):
        with pytest.raises(TypeError, match="Expected bytes-like"):
            hash_bytes("not bytes")  # type: ignore

    def test_rejects_int(self):
        with pytest.raises(TypeError, match="Expected bytes-like"):
            hash_bytes(42)  # type: ignore


class TestHashFile:
    def test_small_file(self, tmp_path):
        f = tmp_path / "test.txt"
        content = b"hello file"
        f.write_bytes(content)
        expected = hashlib.sha256(content).hexdigest()
        assert hash_file(str(f)) == expected

    def test_path_object(self, tmp_path):
        f = tmp_path / "test.bin"
        content = os.urandom(256)
        f.write_bytes(content)
        expected = hashlib.sha256(content).hexdigest()
        assert hash_file(f) == expected

    def test_large_file_chunked(self, tmp_path):
        f = tmp_path / "large.bin"
        content = os.urandom(100_000)
        f.write_bytes(content)
        expected = hashlib.sha256(content).hexdigest()
        assert hash_file(str(f)) == expected

    def test_empty_file(self, tmp_path):
        f = tmp_path / "empty"
        f.write_bytes(b"")
        expected = hashlib.sha256(b"").hexdigest()
        assert hash_file(str(f)) == expected

    def test_file_not_found(self):
        with pytest.raises(FileNotFoundError):
            hash_file("/nonexistent/path/file.txt")

    def test_directory_raises(self, tmp_path):
        with pytest.raises(IsADirectoryError):
            hash_file(str(tmp_path))
