"""Tests para extract_exif_metadata."""

import os
import sys

from PIL import Image
from PIL.ExifTags import Base, GPS, IFD
from PIL.TiffImagePlugin import IFDRational

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from cybersecurity.extract_exif_metadata import extract_exif_metadata


def _make_png_without_exif(path: str) -> None:
    """Crea un PNG pequeño sin EXIF."""
    Image.new("RGB", (4, 4), (10, 20, 30)).save(path, format="PNG")


def _make_jpeg_with_exif(path: str) -> None:
    """Crea un JPEG pequeño con EXIF de camara/software/fecha."""
    img = Image.new("RGB", (4, 4), (200, 100, 50))
    exif = img.getexif()
    exif[Base.Make.value] = "TestCam"
    exif[Base.Model.value] = "Model X"
    exif[Base.Software.value] = "PyTestRig 1.0"
    exif[Base.DateTime.value] = "2024:08:12 19:43:07"
    # DateTimeOriginal vive en el sub-IFD EXIF.
    exif_ifd = exif.get_ifd(IFD.Exif)
    exif_ifd[Base.DateTimeOriginal.value] = "2024:08:12 19:43:07"
    img.save(path, format="JPEG", exif=exif)


def _make_jpeg_with_gps(path: str) -> None:
    """Crea un JPEG con GPSInfo en DMS, hemisferio sur y oeste."""
    img = Image.new("RGB", (4, 4), (0, 128, 64))
    exif = img.getexif()
    gps_ifd = exif.get_ifd(IFD.GPSInfo)
    # 40 deg, 25 min, 0.48 seg => 40.41680 grados.
    gps_ifd[GPS.GPSLatitude.value] = (
        IFDRational(40, 1),
        IFDRational(25, 1),
        IFDRational(48, 100),
    )
    gps_ifd[GPS.GPSLatitudeRef.value] = "S"  # hemisferio sur => negativo
    # 3 deg, 42 min, 13.68 seg => 3.7038 grados.
    gps_ifd[GPS.GPSLongitude.value] = (
        IFDRational(3, 1),
        IFDRational(42, 1),
        IFDRational(1368, 100),
    )
    gps_ifd[GPS.GPSLongitudeRef.value] = "W"  # oeste => negativo
    img.save(path, format="JPEG", exif=exif)


def test_imagen_sin_exif_png_devuelve_none(tmp_path):
    """imagen sin EXIF (PNG) devuelve campos None y raw vacio."""
    p = str(tmp_path / "plain.png")
    _make_png_without_exif(p)

    meta = extract_exif_metadata(p)

    assert meta["datetime"] is None
    assert meta["camera_make"] is None
    assert meta["camera_model"] is None
    assert meta["software"] is None
    assert meta["gps_lat"] is None
    assert meta["gps_lon"] is None
    assert meta["raw"] == {}


def test_imagen_con_exif_devuelve_camara_software_fecha(tmp_path):
    """imagen con EXIF devuelve camara, software y fecha."""
    p = str(tmp_path / "withexif.jpg")
    _make_jpeg_with_exif(p)

    meta = extract_exif_metadata(p)

    assert meta["camera_make"] == "TestCam"
    assert meta["camera_model"] == "Model X"
    assert meta["software"] == "PyTestRig 1.0"
    assert meta["datetime"] == "2024:08:12 19:43:07"
    assert meta["raw"]  # no vacio


def test_gps_dms_a_grados_decimales_con_signo(tmp_path):
    """GPSInfo DMS se convierte a grados decimales con signo por hemisferio."""
    p = str(tmp_path / "withgps.jpg")
    _make_jpeg_with_gps(p)

    meta = extract_exif_metadata(p)

    assert meta["gps_lat"] is not None
    assert meta["gps_lon"] is not None
    # Sur y Oeste => ambos negativos.
    assert meta["gps_lat"] < 0
    assert meta["gps_lon"] < 0
    assert abs(meta["gps_lat"] - (-40.41680)) < 1e-4
    assert abs(meta["gps_lon"] - (-3.7038)) < 1e-4


if __name__ == "__main__":
    import tempfile
    from pathlib import Path

    with tempfile.TemporaryDirectory() as d:
        test_imagen_sin_exif_png_devuelve_none(Path(d))
        test_imagen_con_exif_devuelve_camara_software_fecha(Path(d))
        test_gps_dms_a_grados_decimales_con_signo(Path(d))
    print("Todos los tests pasaron.")
