use super::common::bucketwarden;
use serde_json::Value;

#[test]
fn ops_report_commands_emit_operator_json_reports() {
    let health = bucketwarden()
        .args(["ops", "report", "health", "--bucket", "archive-001"])
        .output()
        .unwrap();
    assert!(health.status.success());
    let value: Value = serde_json::from_slice(&health.stdout).unwrap();
    assert_eq!(value["scope"], "bucket");
    assert_eq!(value["target"], "archive-001");

    let config = bucketwarden()
        .args(["ops", "report", "config", "--bucket", "archive-001"])
        .output()
        .unwrap();
    assert!(config.status.success());
    let value: Value = serde_json::from_slice(&config.stdout).unwrap();
    assert_eq!(value["scope"], "bucket");
    assert!(value["active_storage_backend"].is_string());

    let admin = bucketwarden()
        .args(["ops", "report", "admin-surfaces"])
        .output()
        .unwrap();
    assert!(admin.status.success());
    let value: Value = serde_json::from_slice(&admin.stdout).unwrap();
    assert!(value["storage_backend_admin_surfaces"].is_array());

    let incident = bucketwarden()
        .args(["ops", "report", "incident", "--type", "credential_leak"])
        .output()
        .unwrap();
    assert!(incident.status.success());
    let value: Value = serde_json::from_slice(&incident.stdout).unwrap();
    assert_eq!(value["incident_type"], "credential_leak");

    let evidence = bucketwarden()
        .args(["ops", "report", "evidence-export"])
        .output()
        .unwrap();
    assert!(evidence.status.success());
    let value: Value = serde_json::from_slice(&evidence.stdout).unwrap();
    assert!(value["snapshot_json"].is_string());
}

#[test]
fn readiness_outputs_probe_json() {
    let output = bucketwarden().arg("readiness").output().unwrap();

    assert!(output.status.success());
    let value: Value = serde_json::from_slice(&output.stdout).unwrap();
    assert_eq!(value["status"], "degraded");
    assert_eq!(value["checks"]["runtime"], "degraded");
    assert_eq!(value["checks"]["audit_log"], "ready");
}

#[test]
fn diagnostics_outputs_operator_summary_json() {
    let output = bucketwarden().arg("diagnostics").output().unwrap();

    assert!(output.status.success());
    let value: Value = serde_json::from_slice(&output.stdout).unwrap();
    assert_eq!(value["status"], "degraded");
    assert_eq!(value["runtime"]["status"], "degraded");
    assert_eq!(value["certification"]["full_repository_certified"], false);
}

#[test]
fn metrics_outputs_prometheus_text() {
    let output = bucketwarden().arg("metrics").output().unwrap();

    assert!(output.status.success());
    let stdout = String::from_utf8(output.stdout).unwrap();
    assert!(stdout.contains("# TYPE bucketwarden_bucket_count gauge"));
    assert!(stdout.contains("bucketwarden_bucket_count 0"));
    assert!(stdout.contains("bucketwarden_audit_events_total{outcome=\"allowed\"} 2"));
    assert!(stdout.contains("bucketwarden_replication_records_total{action=\"put_object\"} 0"));
}

#[test]
fn audit_export_and_replication_status_are_operator_commands() {
    let audit = bucketwarden().args(["audit", "export"]).output().unwrap();
    assert!(audit.status.success());
    let stdout = String::from_utf8(audit.stdout).unwrap();
    let audit_events = stdout
        .lines()
        .map(|line| serde_json::from_str::<Value>(line).expect("audit json line"))
        .collect::<Vec<_>>();
    assert!(audit_events.iter().any(|event| {
        event["action"] == "auth:AssignOperatorRole"
            && event["subject"] == "operator"
            && event["resource"] == "operator"
            && event["outcome"] == "Allowed"
            && event["detail"] == "ClusterAdmin:*"
    }));

    let replication = bucketwarden()
        .args(["replication", "status"])
        .output()
        .unwrap();
    assert!(replication.status.success());
    let value: Value = serde_json::from_slice(&replication.stdout).unwrap();
    assert_eq!(value["status"], "ok");
    assert!(value["last_sequence"].is_null());
}
