from pathlib import Path

import trimesh
from fastapi.testclient import TestClient

import app as app_module
from flexiforge.shire_bridge import ShireJobStore


def test_shire_api_stops_before_export_without_second_approval(tmp_path: Path, monkeypatch):
    models = tmp_path / "models"
    exports = tmp_path / "exports"
    jobs = tmp_path / "jobs"
    models.mkdir(); exports.mkdir(); jobs.mkdir()
    monkeypatch.setattr(app_module, "MODELS", models)
    monkeypatch.setattr(app_module, "EXPORTS", exports)
    monkeypatch.setattr(app_module, "SHIRE_JOBS", jobs)
    monkeypatch.setattr(app_module, "shire_jobs", ShireJobStore(jobs, models, exports))

    mesh = trimesh.creation.box(extents=[70, 26, 15])
    stl = mesh.export(file_type="stl")
    client = TestClient(app_module.app)

    uploaded = client.post("/api/upload", files={"file": ("test.stl", stl, "model/stl")})
    assert uploaded.status_code == 200
    model_id = uploaded.json()["model_id"]

    created = client.post("/api/shire/jobs", json={
        "model_id": model_id,
        "project_name": "API Dragon",
        "intent": "Articulate the tail",
        "movement": "wiggle",
        "clearance_mm": 0.35,
        "max_suggestions": 5,
    })
    assert created.status_code == 200
    job = created.json()
    selected = client.post(
        f"/api/shire/jobs/{job['job_id']}/select",
        json={"suggestion_id": job["suggestions"][0]["suggestion_id"], "requested_type": "hinge"},
    )
    assert selected.status_code == 200

    token = client.post(f"/api/shire/jobs/{job['job_id']}/request-design-approval").json()["approval_token"]
    assert client.post(f"/api/shire/jobs/{job['job_id']}/approve-design", json={"token": token}).status_code == 200
    assert client.post(f"/api/shire/jobs/{job['job_id']}/forge").status_code == 200
    validated = client.post(f"/api/shire/jobs/{job['job_id']}/validate")
    assert validated.status_code == 200
    assert validated.json()["state"] == "VALIDATED"

    # Export is still blocked until a separate immutable export approval is recorded.
    blocked = client.post(f"/api/shire/jobs/{job['job_id']}/export")
    assert blocked.status_code == 422
