from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path

import pytest

from nanobot.config.loader import set_config_path
from nanobot.utils.artifacts import (
    ArtifactError,
    decode_image_data_url,
    store_generated_image_artifact,
)

PNG_DATA_URL = (
    "data:image/png;base64,"
    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="
)


def test_decode_image_data_url_validates_image_payload() -> None:
    raw, mime = decode_image_data_url(PNG_DATA_URL)

    assert raw.startswith(b"\x89PNG")
    assert mime == "image/png"

    with pytest.raises(ArtifactError):
        decode_image_data_url("data:image/png;base64,not-base64")


def test_store_generated_image_artifact_writes_image_and_sidecar(tmp_path: Path) -> None:
    set_config_path(tmp_path / "config.json")
    created_at = datetime(2026, 5, 8, 12, 0, tzinfo=timezone.utc)

    artifact = store_generated_image_artifact(
        PNG_DATA_URL,
        prompt="draw a tiny pixel",
        model="openai/gpt-5.4-image-2",
        source_images=["/tmp/ref.png"],
        save_dir="generated",
        created_at=created_at,
    )

    image_path = Path(artifact["path"])
    assert image_path.is_file()
    assert image_path.parent == tmp_path / "media" / "generated" / "2026-05-08"
    assert artifact["id"].startswith("img_")
    assert artifact["mime"] == "image/png"

    sidecar = image_path.with_suffix(".json")
    metadata = json.loads(sidecar.read_text(encoding="utf-8"))
    assert metadata["path"] == str(image_path)
    assert metadata["source_images"] == ["/tmp/ref.png"]


def test_store_generated_image_artifact_rejects_unsafe_save_dir(tmp_path: Path) -> None:
    set_config_path(tmp_path / "config.json")

    with pytest.raises(ArtifactError):
        store_generated_image_artifact(
            PNG_DATA_URL,
            prompt="x",
            model="m",
            save_dir="../outside",
        )
