from fastapi.testclient import TestClient
import cv2
import numpy as np

from app.main import app


def test_flood_volume_change():
    client = TestClient(app)
    response = client.post(
        "/api/v1/pointcloud/analyze",
        json={
            "resource": {"resource_id": "pc-1", "storage_url": "s3://bucket/flood.tif", "metadata": {"volume_change_m3": 2.4}},
            "scenes": ["防洪点精密监测"],
        },
    )
    assert response.status_code == 200
    assert response.json()["results"][0]["measurements"]["volume_change_m3"] == 2.4


def test_change_detector_contract():
    client = TestClient(app)
    response = client.post(
        "/api/v1/pointcloud/test",
        json={
            "model_group": "change-detector",
            "model_version": "v1.1.0",
            "resource": {"resource_id": "raster-1", "metadata": {"change_area_m2": 18.6}},
            "scenes": ["彩钢板清理"],
            "parameters": {"change_threshold": 0.25, "registration_precision_m": 0.2},
            "deployment_id": "runtime-test-change",
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["model"]["name"] == "change-detector"
    assert body["results"][0]["category"] == "变化区域"
    assert body["results"][0]["measurements"]["change_area_m2"] == 18.6
    assert body["results"][0]["attributes"]["execution_mode"] == "baseline"
    assert body["results"][0]["attributes"]["deployment_id"] == "runtime-test-change"


def test_cpu_runtime_reports_spatial_models():
    client = TestClient(app)
    response = client.get("/api/v1/runtime")
    assert response.status_code == 200
    body = response.json()
    assert body["profile"] == "cpu-local"
    assert body["max_concurrency"] == 1
    groups = {item["model_group"] for item in body["models"]}
    assert groups == {"change-detector", "pointcloud-analyzer"}
    assert {item["model_version"] for item in body["models"]} == {"cpu-v1.0.0"}
    assert body["execution_provider_ready"] is True


def test_change_detector_uses_opencv_cpu_when_two_images_exist(tmp_path):
    baseline = np.zeros((96, 96, 3), dtype=np.uint8)
    current = baseline.copy()
    cv2.rectangle(current, (30, 30), (64, 64), (255, 255, 255), -1)
    baseline_path = tmp_path / "baseline.png"
    current_path = tmp_path / "current.png"
    cv2.imwrite(str(baseline_path), baseline)
    cv2.imwrite(str(current_path), current)

    client = TestClient(app)
    response = client.post(
        "/api/v1/pointcloud/test",
        json={
            "model_group": "change-detector",
            "model_version": "cpu-v1.0.0",
            "resource": {
                "resource_id": "change-real",
                "storage_url": current_path.as_uri(),
                "metadata": {"baseline_storage_url": baseline_path.as_uri()},
            },
            "scenes": ["彩钢板清理"],
            "parameters": {
                "change_threshold": 0.25,
                "target_resolution_m": 0.1,
                "minimum_area_m2": 0.1,
                "morphology_kernel": 1,
            },
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["results"]
    assert body["results"][0]["attributes"]["execution_mode"] == "opencv-cpu"
