"""メタデータ除去（要件定義書 4.5「メタデータ除去」）。

PDFプロパティ、画像Exif（GPS含む）、音声・動画タグ情報を一括除去する。
根拠：docs/02_constraints-report.md 第3章5節（Q&A 10頁、操作マニュアル別紙3）。

Office文書プロパティの除去は、Office文書自体が書き出し対象（記録対応形式）
ではない（C分類＝要変換。4.4節の形式変換機能はチェック専念方針により廃止）
ため対象としない。

このモジュールは実際にファイルを変更する処理（除去済みコピーの生成）を
含むため、呼び出し側は必ず確認UI（ui/write_review_dialog.py の逐次レビュー
画面）でユーザーの確認を得たうえで実行すること（CLAUDE.md「絶対に譲れない
設計原則」3）。元ファイルは変更しない（出力先へ除去済みコピーを新規に書き出す）。

【既知の制約】MP3/MP4のタグ除去はmutagenで実装しているが、自動テストによる
検証はPDF・画像（JPEG/PNG）にとどまる（有効なMP3/MP4フィクスチャの合成が
複雑なため）。音声・動画ファイルでの実運用前には手動確認を推奨する。
"""

from __future__ import annotations

import shutil
from pathlib import Path

import pikepdf
from PIL import Image

_IMAGE_FORMATS = {"JPEG", "PNG"}
_AUDIO_VIDEO_FORMATS = {"MP3", "MP4"}


def strip_pdf_metadata(src: Path, dest: Path) -> None:
    """PDFのdocinfo（作成者・編集日時等）及びXMPメタデータを除去したコピーを作成する。"""
    with pikepdf.open(src) as pdf:
        for key in list(pdf.docinfo.keys()):
            del pdf.docinfo[key]
        with pdf.open_metadata() as meta:
            meta.clear()
        pdf.save(dest)


def strip_image_metadata(src: Path, dest: Path) -> None:
    """画像のExif（GPS位置情報等）を除去したコピーを作成する。

    ピクセルデータのみを新規Imageオブジェクトへ複製することで、Exif・ICC
    プロファイル・PNGテキストチャンク等の付随情報を一切引き継がない。
    """
    with Image.open(src) as image:
        data = list(image.getdata())
        clean = Image.new(image.mode, image.size)
        clean.putdata(data)
        clean.save(dest)


def strip_audio_video_metadata(src: Path, dest: Path) -> None:
    """音声・動画のタグ情報（作成者・作成ソフト等）を除去したコピーを作成する。"""
    import mutagen

    shutil.copy2(src, dest)
    audio = mutagen.File(dest, easy=True)
    if audio is not None and audio.tags is not None:
        audio.delete()
        audio.save()


def strip_metadata(src: Path, dest: Path, detected_format: str) -> None:
    """検出形式に応じたメタデータ除去処理を実行する。"""
    if detected_format == "PDF":
        strip_pdf_metadata(src, dest)
    elif detected_format in _IMAGE_FORMATS:
        strip_image_metadata(src, dest)
    elif detected_format in _AUDIO_VIDEO_FORMATS:
        strip_audio_video_metadata(src, dest)
    else:
        # 対応外形式（想定外の呼び出し）は安全側としてそのままコピーする。
        shutil.copy2(src, dest)
