"""image_transform：Pillow 操作与 help；OpenCV 可选。"""

from __future__ import annotations

from pathlib import Path

from PIL import Image

from aicd.config import PathPolicyConfig
from aicd.tools.image_transform import list_image_operations, run_image_transform
from aicd.tools.path_policy import PathPolicy


def test_list_operations_contains_resize() -> None:
    assert "resize" in list_image_operations()
    assert "help" not in list_image_operations()


def test_help_returns_schema(tmp_path: Path) -> None:
    pol = PathPolicy(PathPolicyConfig(full_disk=True))
    r = run_image_transform(
        "help",
        tmp_path / "i.png",
        tmp_path / "o.png",
        params={},
        policy_check=pol.check_allowed,
    )
    assert r["ok"] is True
    assert "operations_help" in r


def test_solid_canvas_no_input_file(tmp_path: Path) -> None:
    pol = PathPolicy(PathPolicyConfig(full_disk=True))
    out = tmp_path / "canvas.png"
    r = run_image_transform(
        "solid_canvas",
        tmp_path / "nonexistent_in.png",
        out,
        params={"width": 120, "height": 80, "fill": [240, 248, 255, 255]},
        policy_check=pol.check_allowed,
    )
    assert r["ok"] is True
    assert out.is_file()
    with Image.open(out) as im:
        assert im.size == (120, 80)


def test_resize_fit(tmp_path: Path) -> None:
    pol = PathPolicy(PathPolicyConfig(full_disk=True))
    src = tmp_path / "a.png"
    Image.new("RGBA", (200, 100), (255, 0, 0, 255)).save(src)
    dst = tmp_path / "b.png"
    r = run_image_transform(
        "resize",
        src,
        dst,
        params={"width": 100, "height": 100, "mode": "fit"},
        policy_check=pol.check_allowed,
    )
    assert r["ok"] is True
    with Image.open(dst) as im:
        assert im.size == (100, 50)


def test_draw_and_overlay(tmp_path: Path) -> None:
    pol = PathPolicy(PathPolicyConfig(full_disk=True))
    base = tmp_path / "base.png"
    Image.new("RGBA", (100, 100), (200, 200, 200, 255)).save(base)
    ov = tmp_path / "ov.png"
    Image.new("RGBA", (20, 20), (0, 0, 255, 128)).save(ov)
    mid = tmp_path / "mid.png"
    r1 = run_image_transform(
        "draw_rectangle",
        base,
        mid,
        params={
            "xyxy": [10, 10, 90, 90],
            "outline": [0, 0, 0, 255],
            "width": 3,
        },
        policy_check=pol.check_allowed,
    )
    assert r1["ok"] is True
    out = tmp_path / "final.png"
    r2 = run_image_transform(
        "paste_overlay",
        mid,
        out,
        params={"overlay_path": str(ov), "x": 40, "y": 40, "alpha": 0.8},
        policy_check=pol.check_allowed,
    )
    assert r2["ok"] is True


def test_edge_canny_if_cv2() -> None:
    try:
        import cv2  # noqa: F401
    except ImportError:
        return
    from tempfile import mkdtemp

    pol = PathPolicy(PathPolicyConfig(full_disk=True))
    d = Path(mkdtemp())
    src = d / "s.png"
    Image.new("RGBA", (64, 64), (128, 128, 128, 255)).save(src)
    dst = d / "e.png"
    r = run_image_transform(
        "edge_canny",
        src,
        dst,
        params={"low": 40, "high": 120},
        policy_check=pol.check_allowed,
    )
    assert r["ok"] is True
    assert dst.stat().st_size > 50
