from pathlib import Path

import pikepdf
from PIL import Image

from fixtures.generate_fixtures import make_a4_pdf, make_image_with_metadata
from mints_prep.processors.metadata_remover import (
    strip_image_metadata,
    strip_metadata,
    strip_pdf_metadata,
)


def test_strip_pdf_metadata_removes_author_and_title(tmp_path: Path):
    src = make_a4_pdf(tmp_path / "with_meta.pdf", with_metadata=True)
    with pikepdf.open(src) as pdf:
        assert "/Author" in pdf.docinfo.keys()

    dest = tmp_path / "stripped.pdf"
    strip_pdf_metadata(src, dest)

    with pikepdf.open(dest) as pdf:
        keys = [str(k) for k in pdf.docinfo.keys()] if pdf.docinfo else []
        assert "/Author" not in keys
        assert "/Title" not in keys

    # 元ファイルは変更されない
    with pikepdf.open(src) as pdf:
        assert "/Author" in pdf.docinfo.keys()


def test_strip_pdf_metadata_clears_xmp(tmp_path: Path):
    src = make_a4_pdf(tmp_path / "with_meta.pdf", with_metadata=True)
    dest = tmp_path / "stripped.pdf"
    strip_pdf_metadata(src, dest)

    with pikepdf.open(dest) as pdf:
        with pdf.open_metadata() as meta:
            xmp = dict(meta)
    # dc:title等の実質的なメタデータは残らない（Producer等の技術的な
    # 自動付与フィールドのみが再付与されるのは許容する）。
    assert "{http://purl.org/dc/elements/1.1/}title" not in xmp


def test_strip_image_metadata_removes_exif(tmp_path: Path):
    src = make_image_with_metadata(tmp_path / "with_exif.jpg")
    with Image.open(src) as img:
        assert len(img.getexif()) > 0

    dest = tmp_path / "stripped.jpg"
    strip_image_metadata(src, dest)

    with Image.open(dest) as img:
        assert len(img.getexif()) == 0

    # 元ファイルは変更されない
    with Image.open(src) as img:
        assert len(img.getexif()) > 0


def test_strip_image_metadata_preserves_pixel_data(tmp_path: Path):
    src = tmp_path / "colored.png"
    Image.new("RGB", (4, 4), color=(12, 34, 56)).save(src)

    dest = tmp_path / "stripped.png"
    strip_image_metadata(src, dest)

    with Image.open(dest) as img:
        assert img.getpixel((0, 0)) == (12, 34, 56)
        assert img.size == (4, 4)


def test_strip_metadata_dispatches_by_format(tmp_path: Path):
    pdf_src = make_a4_pdf(tmp_path / "a.pdf", with_metadata=True)
    dest = tmp_path / "a_out.pdf"
    strip_metadata(pdf_src, dest, "PDF")
    with pikepdf.open(dest) as pdf:
        assert "/Author" not in [str(k) for k in pdf.docinfo.keys()]


def test_strip_metadata_unknown_format_falls_back_to_copy(tmp_path: Path):
    src = tmp_path / "data.bin"
    src.write_bytes(b"raw bytes")
    dest = tmp_path / "data_out.bin"

    strip_metadata(src, dest, "UNKNOWN")

    assert dest.read_bytes() == b"raw bytes"
