"""
Tests for clawID video watermarking.

Requires imageio[ffmpeg] to be installed.
Tests use tiny in-memory GIF sequences to avoid ffmpeg codec dependency.
"""

import io
import numpy as np
import pytest
from PIL import Image

pytest.importorskip("imageio", reason="imageio required for video tests")

import imageio.v3 as iio

from clawid.video import embed_video, detect_video


# ── helpers ───────────────────────────────────────────────────────────────────

def _make_test_video(path: str, n_frames: int = 20, size: tuple = (512, 512)):
    """Write a small GIF video with random frames."""
    rng = np.random.default_rng(42)
    frames = [rng.integers(0, 256, (*size, 3), dtype=np.uint8) for _ in range(n_frames)]
    from PIL import Image as _Image
    pil_frames = [_Image.fromarray(f) for f in frames]
    pil_frames[0].save(path, save_all=True, append_images=pil_frames[1:])


# ── basic round-trip ──────────────────────────────────────────────────────────

def test_embed_video_creates_output(tmp_path):
    """embed_video creates an output file and returns metadata with clawid."""
    src = str(tmp_path / "in.tiff")
    out = str(tmp_path / "out.tiff")
    _make_test_video(src)

    meta = embed_video(src, out, {'uid': 'video_user', 'platform': 'hawky.ai'})

    import os
    assert os.path.exists(out)
    assert 'clawid' in meta
    assert len(meta['clawid']) == 36     # UUID format
    assert meta['uid'] == 'video_user'


def test_embed_video_returns_clawid_uuid(tmp_path):
    """clawid in returned metadata is a valid UUID."""
    import re
    src = str(tmp_path / "in.tiff")
    out = str(tmp_path / "out.tiff")
    _make_test_video(src)

    meta = embed_video(src, out, {'uid': 'u1'})
    assert re.match(
        r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',
        meta['clawid'],
    )


def test_embed_video_consistent_clawid_across_frames(tmp_path):
    """All frames get the same clawid (so detection succeeds from any frame)."""
    src = str(tmp_path / "in.tiff")
    out = str(tmp_path / "out.tiff")
    _make_test_video(src, n_frames=15)

    meta = embed_video(src, out, {'uid': 'u2'}, frame_stride=3)

    # Detect directly from each watermarked frame
    from clawid.core.detect import detect
    clawids = set()
    for frame in iio.imiter(out, plugin='pillow'):
        pil = Image.fromarray(frame)
        r = detect(pil)
        if r:
            clawids.add(r['clawid'])

    assert len(clawids) == 1, f"Expected 1 unique clawid, found: {clawids}"
    assert list(clawids)[0] == meta['clawid']


# ── detection ─────────────────────────────────────────────────────────────────

def test_detect_video_finds_watermark(tmp_path):
    """detect_video returns correct metadata from a watermarked video."""
    src = str(tmp_path / "in.tiff")
    out = str(tmp_path / "out.tiff")
    _make_test_video(src)

    meta = embed_video(src, out, {'uid': 'bob', 'platform': 'test'}, frame_stride=3)
    result = detect_video(out, frame_stride=3)

    assert result is not None, "detect_video returned None"
    assert result['uid'] == 'bob'
    assert result['clawid'] == meta['clawid']


def test_detect_video_clean_video_returns_none(tmp_path):
    """detect_video returns None for an unwatermarked video."""
    src = str(tmp_path / "clean.tiff")
    _make_test_video(src)

    result = detect_video(src)
    assert result is None


def test_detect_video_custom_clawid(tmp_path):
    """embed_video preserves a pre-set clawid UUID."""
    import uuid
    src = str(tmp_path / "in.tiff")
    out = str(tmp_path / "out.tiff")
    _make_test_video(src)

    custom_id = str(uuid.uuid4())
    meta = embed_video(src, out, {'uid': 'alice', 'clawid': custom_id})
    result = detect_video(out)

    assert result is not None
    assert result['clawid'] == custom_id
