from rights_filter.analysis.preprocessing import (
    ImagePayload,
    PreprocessingError,
    build_face_crop_derivatives,
    build_external_derivative,
)
from rights_filter.domain.records import DataClass


def test_external_derivative_removes_exif_and_caps_dimensions():
    original = ImagePayload(
        content=b"image-bytes",
        width=4000,
        height=2000,
        metadata={"EXIF": "camera serial", "author": "user"},
    )

    derivative = build_external_derivative(original, max_side=1600)

    assert derivative.width == 1600
    assert derivative.height == 800
    assert derivative.metadata == {}
    assert derivative.data_class == DataClass.EXTERNAL_DERIVATIVE
    assert derivative.content == b"image-bytes"


def test_small_image_is_still_metadata_stripped():
    original = ImagePayload(
        content=b"small-image",
        width=800,
        height=600,
        metadata={"GPS": "private"},
    )

    derivative = build_external_derivative(original, max_side=1600)

    assert derivative.width == 800
    assert derivative.height == 600
    assert derivative.metadata == {}


def test_empty_image_records_preprocessing_failure():
    original = ImagePayload(content=b"", width=100, height=100, metadata={})

    try:
        build_external_derivative(original)
    except PreprocessingError as error:
        assert "empty image content" in str(error)
    else:
        raise AssertionError("expected preprocessing failure")


def test_avif_external_derivative_is_converted_to_jpeg_when_decodable():
    from io import BytesIO

    from PIL import Image

    source = BytesIO()
    Image.new("RGB", (200, 100), color=(255, 0, 0)).save(source, format="PNG")
    original = ImagePayload(
        content=source.getvalue(),
        width=200,
        height=100,
        metadata={"format": "AVIF", "EXIF": "private"},
    )

    derivative = build_external_derivative(original, max_side=100)

    assert derivative.content.startswith(b"\xff\xd8")
    assert derivative.width == 100
    assert derivative.height == 50
    assert derivative.metadata == {}
    assert derivative.data_class == DataClass.EXTERNAL_DERIVATIVE


def test_face_crop_derivative_uses_only_cropped_pixels_and_strips_metadata():
    from io import BytesIO

    from PIL import Image

    source = BytesIO()
    Image.new("RGB", (200, 100), color=(0, 120, 200)).save(source, format="PNG")
    original = ImagePayload(
        content=source.getvalue(),
        width=200,
        height=100,
        metadata={"EXIF": "camera serial", "GPS": "private"},
    )

    crops = build_face_crop_derivatives(
        original,
        [(50, 20, 60, 40)],
        max_crops=1,
        padding_ratio=0.25,
        max_side=64,
    )

    assert len(crops) == 1
    crop = crops[0]
    assert crop.content.startswith(b"\xff\xd8")
    assert crop.width <= 64
    assert crop.height <= 64
    assert crop.width > 0
    assert crop.height > 0
    assert crop.metadata == {}
    assert crop.data_class == DataClass.EXTERNAL_DERIVATIVE
