from fastapi.testclient import TestClient

from app.cpu_runtime import RuntimeOutcome
from app.engines import VisionInferenceEngine
from app.main import app
from app.schemas import Resource


def test_detect_tower_crane():
    client = TestClient(app)
    response = client.post(
        "/api/v1/inference/detect",
        json={
            "resource": {"resource_id": "res-1", "storage_url": "s3://bucket/image.jpg", "metadata": {"distance_to_track_m": 80}},
            "scenes": ["塔吊"],
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["results"][0]["category"] == "塔吊"
    assert body["results"][0]["measurements"]["distance_to_track_m"] == 80


def test_model_test_uses_requested_version_and_parameters():
    client = TestClient(app)
    response = client.post(
        "/api/v1/inference/test",
        json={
            "model_group": "vision-detector",
            "model_version": "v1.1.0",
            "resource": {"resource_id": "res-test", "metadata": {"scene": "塔吊"}},
            "scenes": ["塔吊"],
            "parameters": {"confidence_threshold": 0.6, "precision": "FP16"},
            "deployment_id": "runtime-test-vision",
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["model"]["version"] == "v1.1.0"
    assert body["parameter_snapshot"]["confidence_threshold"] == 0.6
    assert body["results"][0]["model_version"] == "v1.1.0"
    assert body["results"][0]["attributes"]["execution_mode"] == "baseline"
    assert body["results"][0]["attributes"]["deployment_id"] == "runtime-test-vision"


def test_cpu_runtime_reports_registered_visual_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["runtime_available"] is True
    assert body["max_concurrency"] == 1
    assert body["max_loaded_models"] == 1
    groups = {item["model_group"] for item in body["models"]}
    assert {"vision-detector", "vision-segmenter", "thermal-analyzer"}.issubset(groups)
    assert {item["model_version"] for item in body["models"]} == {"cpu-v1.0.0"}
    assert body["execution_provider_ready"] is True


def test_real_model_group_does_not_drop_other_group_fallback_results():
    class MixedRuntime:
        def infer(self, resource, model_group, parameters):
            if model_group == "vision-detector":
                return RuntimeOutcome(
                    "onnxruntime-cpu",
                    [
                        {
                            "category": "塔吊",
                            "confidence": 0.91,
                            "geometry": {"type": "BBox", "coordinates": [0.1, 0.1, 0.3, 0.4]},
                            "measurements": {},
                        }
                    ],
                    None,
                    18.2,
                    {"runtime": "onnxruntime-cpu"},
                )
            return RuntimeOutcome("baseline", [], "artifact missing", 0.0, {"model_group": model_group})

    engine = VisionInferenceEngine(runtime=MixedRuntime())
    results = engine.infer(Resource(resource_id="mixed", metadata={}), ["鸟巢", "裂缝识别"])
    assert {item.category for item in results} == {"塔吊", "裂缝"}
    assert {item.attributes["execution_mode"] for item in results} == {"onnxruntime-cpu", "baseline"}
