//! Integration tests for agent binary distribution endpoints
//!
//! The agent endpoints (`/api/v1/agent/binary` and `/api/v1/agent/info`) are
//! intentionally unauthenticated — the agent needs to download its binary
//! before it has JWT credentials. An optional `bootstrap_token` can restrict
//! access, but that is validated inside the handler, not via RequireAuth
//! middleware.
//!
//! The test configuration (`config.test.yaml`) does NOT include an `agent`
//! section, so both endpoints return 503 Service Unavailable. This is the
//! correct behaviour: the endpoints are reachable (no 401/404 from middleware)
//! but the feature is not configured.

use axum::http::StatusCode;

#[allow(dead_code)]
mod helpers;
use helpers::TestContext;

// ── /api/v1/agent/info ──────────────────────────────────────────────

#[tokio::test]
#[ignore = "integration test — requires database"]
async fn test_agent_info_not_configured() {
    let ctx = TestContext::new()
        .await
        .expect("Failed to create test context");

    let response = ctx
        .get("/api/v1/agent/info", None)
        .await
        .expect("Failed to make request");

    // Agent config is not set in config.test.yaml, so the handler returns 503.
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);

    let body: serde_json::Value = response.json().await.expect("Failed to parse JSON");
    assert_eq!(body["error"], "Not configured");
}

#[tokio::test]
#[ignore = "integration test — requires database"]
async fn test_agent_info_no_auth_required() {
    // Verify that the endpoint is reachable WITHOUT any JWT token.
    // If RequireAuth middleware were applied, this would return 401.
    // Instead we expect 503 (not configured) — proving the endpoint
    // is publicly accessible.
    let ctx = TestContext::new()
        .await
        .expect("Failed to create test context");

    let response = ctx
        .get("/api/v1/agent/info", None)
        .await
        .expect("Failed to make request");

    // Must NOT be 401 Unauthorized — the endpoint has no auth middleware.
    assert_ne!(
        response.status(),
        StatusCode::UNAUTHORIZED,
        "agent/info should not require authentication"
    );
    // Should be 503 because agent config is absent.
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
}

// ── /api/v1/agent/binary ────────────────────────────────────────────

#[tokio::test]
#[ignore = "integration test — requires database"]
async fn test_agent_binary_not_configured() {
    let ctx = TestContext::new()
        .await
        .expect("Failed to create test context");

    let response = ctx
        .get("/api/v1/agent/binary", None)
        .await
        .expect("Failed to make request");

    // Agent config is not set in config.test.yaml, so the handler returns 503.
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);

    let body: serde_json::Value = response.json().await.expect("Failed to parse JSON");
    assert_eq!(body["error"], "Not configured");
}

#[tokio::test]
#[ignore = "integration test — requires database"]
async fn test_agent_binary_no_auth_required() {
    // Same reasoning as test_agent_info_no_auth_required: the binary
    // download endpoint must be publicly accessible (no RequireAuth).
    // When no bootstrap_token is configured, any caller can reach the
    // handler. We still get 503 because the agent feature itself is
    // not configured in the test environment.
    let ctx = TestContext::new()
        .await
        .expect("Failed to create test context");

    let response = ctx
        .get("/api/v1/agent/binary", None)
        .await
        .expect("Failed to make request");

    // Must NOT be 401 Unauthorized — the endpoint has no auth middleware.
    assert_ne!(
        response.status(),
        StatusCode::UNAUTHORIZED,
        "agent/binary should not require authentication when no bootstrap_token is configured"
    );
    // Should be 503 because agent config is absent.
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
}

#[tokio::test]
#[ignore = "integration test — requires database"]
async fn test_agent_binary_invalid_arch() {
    // Architecture validation (`validate_arch`) rejects unsupported values
    // with 400 Bad Request. However, in the handler the execution order is:
    //   1. validate_token (passes — no bootstrap_token configured)
    //   2. check agent config (fails with 503 — not configured)
    //   3. validate_arch (never reached)
    //
    // So even with an invalid arch like "mips", we get 503 from the config
    // check before the arch is ever validated. The arch validation is covered
    // by unit tests in routes/agent.rs instead.
    let ctx = TestContext::new()
        .await
        .expect("Failed to create test context");

    let response = ctx
        .get("/api/v1/agent/binary?arch=mips", None)
        .await
        .expect("Failed to make request");

    // 503 from the agent-config-not-set check, NOT 400 from arch validation.
    assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
}
