from uuid import UUID
import json
from io import BytesIO
from unittest.mock import MagicMock, patch

from PIL import Image

from awe.util.util import WATERMARK_SUBJECT, add_img_source, build_hidden_watermark, read_img_source, read_media_source, upload_remote_image, write_hidden_watermark_file


def test_build_hidden_watermark_with_uuid_task_id():
    task_id = "550e8400-e29b-41d4-a716-446655440000"
    watermark = build_hidden_watermark(task_id)

    assert watermark["Label"] == "1"
    assert watermark["ContentProducer"] == WATERMARK_SUBJECT
    assert watermark["ContentPropagator"] == WATERMARK_SUBJECT
    assert watermark["ProduceID"] == task_id
    assert watermark["PropagateID"] == task_id
    assert watermark["ReservedCode1"] == "550e8400e29b41d4a716446655440000"
    assert watermark["ReservedCode2"] == "550e8400e29b41d4a716446655440000"


def test_build_hidden_watermark_with_non_uuid_task_id():
    task_id = "Sq1dGBX2Tl"
    watermark = build_hidden_watermark(task_id)

    assert watermark["ProduceID"] == task_id
    assert watermark["PropagateID"] == task_id
    assert watermark["ReservedCode1"] == watermark["ReservedCode2"]

    uuid_obj = UUID(hex=watermark["ReservedCode1"])
    assert uuid_obj.hex == watermark["ReservedCode1"]


def test_read_img_source_returns_watermark_dict(tmp_path):
    source_path = tmp_path / "source.jpg"
    target_path = tmp_path / "target.jpg"
    Image.new("RGB", (8, 8), color="white").save(source_path, format="JPEG")

    watermark = build_hidden_watermark("550e8400-e29b-41d4-a716-446655440000")
    add_img_source(str(source_path), str(target_path), {"watermark": watermark})

    result = read_img_source(str(target_path))

    assert result == watermark


def test_read_img_source_returns_none_without_exif_description(tmp_path):
    image_path = tmp_path / "plain.jpg"
    Image.new("RGB", (8, 8), color="white").save(image_path, format="JPEG")

    result = read_img_source(str(image_path))

    assert result is None


def test_read_img_source_returns_watermark_dict_for_png(tmp_path):
    source_path = tmp_path / "source.png"
    target_path = tmp_path / "target.png"
    Image.new("RGBA", (8, 8), color="white").save(source_path, format="PNG")

    watermark = build_hidden_watermark("550e8400-e29b-41d4-a716-446655440000")
    add_img_source(str(source_path), str(target_path), {"watermark": watermark})

    result = read_img_source(str(target_path))

    assert result == watermark


def test_write_hidden_watermark_file_supports_png_without_compress(tmp_path):
    source_path = tmp_path / "input.png"
    target_path = tmp_path / "output.png"
    Image.new("RGBA", (8, 8), color="white").save(source_path, format="PNG")

    result_path = write_hidden_watermark_file(str(source_path), "Sq1dGBX2Tl", str(target_path), compress=False)

    assert result_path == str(target_path)
    assert read_img_source(str(target_path)) == build_hidden_watermark("Sq1dGBX2Tl")


@patch("awe.util.util._check_ffmpeg_command")
@patch("awe.util.util.subprocess.run")
def test_read_media_source_returns_watermark_dict(mock_run, mock_check_ffmpeg_command):
    watermark = build_hidden_watermark("550e8400-e29b-41d4-a716-446655440000")
    mock_check_ffmpeg_command.return_value = "ffprobe"
    mock_run.return_value = MagicMock(
        stdout=json.dumps({
            "format": {
                "tags": {
                    "comment": json.dumps(watermark, ensure_ascii=False)
                }
            }
        })
    )

    result = read_media_source("/tmp/demo.mp4")

    assert result == watermark


@patch("awe.util.util.upload_file")
@patch("awe.util.util._write_media_watermark")
@patch("awe.util.util.get_content")
def test_upload_remote_image_writes_media_watermark(mock_get_content, mock_write_media_watermark, mock_upload_file):
    mock_get_content.return_value = b"origin-media"
    mock_write_media_watermark.return_value = b"watermarked-media"
    mock_upload_file.return_value = "https://example.com/video.mp4"

    new_path, uploaded_url = upload_remote_image(
        "https://example.com/video.mp4",
        {},
        "2026/03/12/demo.mp4",
        "mp4",
        True,
        "task-001"
    )

    assert new_path == "2026/03/12/demo.mp4"
    assert uploaded_url == "https://example.com/video.mp4"
    mock_write_media_watermark.assert_called_once_with(b"origin-media", "2026/03/12/demo.mp4", "task-001")
    upload_stream = mock_upload_file.call_args.args[0]
    assert isinstance(upload_stream, BytesIO)
    assert upload_stream.getvalue() == b"watermarked-media"
