"""Basic tests for image hashing."""

from io import BytesIO

import pytest
from PIL import Image

from soosef.verisoo.hashing import hash_image, perceptual_distance, is_same_image


def create_test_image(width: int = 100, height: int = 100, color: tuple = (255, 0, 0)) -> bytes:
    """Create a simple test image."""
    img = Image.new("RGB", (width, height), color)
    buffer = BytesIO()
    img.save(buffer, format="PNG")
    return buffer.getvalue()


class TestHashImage:
    """Tests for hash_image function."""

    def test_hash_returns_all_components(self):
        """Hash should return sha256, phash, and dhash."""
        image_data = create_test_image()
        hashes = hash_image(image_data)

        assert hashes.sha256
        assert hashes.phash
        assert hashes.dhash
        assert len(hashes.sha256) == 64  # SHA-256 hex

    def test_identical_images_same_hash(self):
        """Identical bytes should produce identical hashes."""
        image_data = create_test_image()
        hash1 = hash_image(image_data)
        hash2 = hash_image(image_data)

        assert hash1.sha256 == hash2.sha256
        assert hash1.phash == hash2.phash
        assert hash1.dhash == hash2.dhash

    def test_different_images_different_hash(self):
        """Different images should produce different SHA-256."""
        red = create_test_image(color=(255, 0, 0))
        blue = create_test_image(color=(0, 0, 255))

        hash_red = hash_image(red)
        hash_blue = hash_image(blue)

        assert hash_red.sha256 != hash_blue.sha256


class TestPerceptualDistance:
    """Tests for perceptual distance calculation."""

    def test_identical_hashes_zero_distance(self):
        """Identical hashes should have zero distance."""
        h = "0123456789abcdef"
        assert perceptual_distance(h, h) == 0

    def test_different_hashes_nonzero_distance(self):
        """Different hashes should have positive distance."""
        h1 = "0000000000000000"
        h2 = "0000000000000001"
        assert perceptual_distance(h1, h2) == 1

    def test_completely_different_max_distance(self):
        """Completely different hashes should have max distance."""
        h1 = "0000000000000000"
        h2 = "ffffffffffffffff"
        assert perceptual_distance(h1, h2) == 64  # 16 hex chars = 64 bits


class TestIsSameImage:
    """Tests for image comparison."""

    def test_exact_match(self):
        """Identical bytes should be exact match."""
        image_data = create_test_image()
        hash1 = hash_image(image_data)
        hash2 = hash_image(image_data)

        is_same, reason = is_same_image(hash1, hash2)
        assert is_same
        assert reason == "exact"
