import assert from "node:assert/strict";
import test from "node:test";

import { __testHooks } from "./dev-edge-health-smoke-lib.mjs";

test("runtime DB readiness preserves dns resolution classification", () => {
  const readiness = __testHooks.summarizeRuntimeDbReadiness(
    {
      configReady: true,
      liveConnected: false,
      liveDbEvidence: false,
      connectionAttempted: true,
      connectionResult: "dns_error",
      fields: [
        { name: "HWLAB_CLOUD_DB_URL", present: true },
        { name: "HWLAB_CLOUD_DB_SSL_MODE", present: true }
      ],
      secretRefs: [
        {
          env: "HWLAB_CLOUD_DB_URL",
          secretName: "hwlab-cloud-api-dev-db",
          secretKey: "database-url",
          present: true,
          envInjected: true
        }
      ],
      connection: {
        attempted: true,
        result: "dns_error",
        classification: "dns_resolution_failed",
        endpointSource: "secret-url-host",
        endpointRedacted: true,
        valueRedacted: true
      },
      redaction: { valuesRedacted: true },
      safety: { valuesRedacted: true, liveDbEvidence: false },
      blocker: "DB endpoint DNS resolution failed from the cloud-api runtime"
    },
    {
      observable: true,
      secretName: "hwlab-cloud-api-dev-db",
      secretKey: "database-url",
      secretPresent: true,
      secretKeyPresent: true,
      secretValueRead: false,
      redacted: true
    }
  );

  assert.equal(readiness.status, "blocked");
  assert.equal(readiness.connectionResult, "dns_error");
  assert.equal(readiness.connectionClassification, "dns_resolution_failed");
  assert.equal(readiness.endpointSource, "secret-url-host");
  assert.equal(readiness.optionalPublicDnsAlias.source, "optional-public-dns-alias");
  assert.equal(readiness.optionalPublicDnsAlias.requiredForReadiness, false);
  assert.equal(readiness.optionalPublicDnsAlias.usedForProbe, false);
  assert.equal(readiness.liveConnected, false);
  assert.equal(readiness.liveDbEvidence, false);
  assert.equal(readiness.secretMaterialRead, false);
  assert.equal(readiness.evidence[0].classification, "dns_resolution_failed");
  assert.equal(readiness.evidence[0].endpointSource, "secret-url-host");
});

test("runtime DB readiness does not pass when live success uses a non-authoritative DB endpoint source", () => {
  const readiness = __testHooks.summarizeRuntimeDbReadiness(
    {
      configReady: true,
      ready: true,
      connected: true,
      liveConnected: true,
      liveDbEvidence: true,
      connectionAttempted: true,
      connectionResult: "connected",
      endpointSource: "optional-public-dns-alias",
      fields: [
        { name: "HWLAB_CLOUD_DB_URL", present: true },
        { name: "HWLAB_CLOUD_DB_SSL_MODE", present: true }
      ],
      secretRefs: [
        {
          env: "HWLAB_CLOUD_DB_URL",
          secretName: "hwlab-cloud-api-dev-db",
          secretKey: "database-url",
          present: true,
          envInjected: true
        }
      ],
      connection: {
        attempted: true,
        result: "connected",
        classification: "tcp_connected",
        endpointSource: "optional-public-dns-alias",
        endpointRedacted: true,
        valueRedacted: true
      },
      redaction: { valuesRedacted: true },
      safety: { valuesRedacted: true, liveDbEvidence: true }
    },
    {
      observable: true,
      secretName: "hwlab-cloud-api-dev-db",
      secretKey: "database-url",
      secretPresent: true,
      secretKeyPresent: true,
      secretValueRead: false,
      redacted: true
    }
  );

  assert.equal(readiness.status, "blocked");
  assert.equal(readiness.liveConnected, true);
  assert.equal(readiness.endpointSource, "optional-public-dns-alias");
  assert.match(readiness.blocker, /Secret URL host/u);
});

test("parallel blockers keep DB readiness and provider Secret gaps independent", () => {
  const edgeHealth = {
    runtimeDbReadiness: {
      status: "blocked",
      connectionResult: "dns_error",
      connectionClassification: "dns_resolution_failed",
      blocker: "DB endpoint DNS resolution failed from the cloud-api runtime"
    },
    providerSecretReadiness: {
      status: "blocked",
      classification: "provider_secret_missing",
      blocker: "Code Agent provider Secret hwlab-code-agent-provider/openai-api-key is not present as key-presence evidence"
    }
  };

  const blockers = __testHooks.classifyParallelBlockers(edgeHealth);
  assert.deepEqual(
    blockers.map((blocker) => blocker.scope),
    ["cloud-api-db", "code-agent-provider-secret"]
  );
  assert.equal(blockers[0].classification, "dns_resolution_failed");
  assert.equal(blockers[0].sourceIssue, "pikasTech/HWLAB#49");
  assert.equal(blockers[1].classification, "provider_secret_missing");
  assert.equal(blockers[1].sourceIssue, "pikasTech/HWLAB#143");
  assert.ok(blockers[0].impact.separateFrom.includes("pikasTech/HWLAB#143 provider Secret"));
  assert.ok(blockers[1].impact.separateFrom.includes("pikasTech/HWLAB#49 DB live readiness"));
});

test("provider Secret blocker remains open even if DB is not blocked", () => {
  const blockers = __testHooks.classifyParallelBlockers({
    runtimeDbReadiness: { status: "pass" },
    providerSecretReadiness: {
      status: "blocked",
      classification: "provider_secret_missing",
      blocker: "Code Agent provider Secret hwlab-code-agent-provider/openai-api-key is not present as key-presence evidence"
    }
  });

  assert.equal(blockers.length, 1);
  assert.equal(blockers[0].scope, "code-agent-provider-secret");
  assert.equal(blockers[0].type, "agent_blocker");
});

test("milestone impact does not promote DB or provider evidence into M3/M4/M5", () => {
  const impact = __testHooks.classifyMilestoneImpact({
    runtimeDbReadiness: { status: "blocked" },
    providerSecretReadiness: { status: "blocked" }
  });

  assert.equal(impact.M3.status, "separate_blocker");
  assert.deepEqual(impact.M4.blockedBy, ["cloud-api-db-live", "code-agent-provider-secret"]);
  assert.deepEqual(impact.M5.blockedBy, ["cloud-api-db-live", "code-agent-provider-secret"]);
  assert.match(impact.M5.summary, /cannot be promoted/u);
});
