const assert = require("assert");
const fs = require("fs");
const path = require("path");

const root = path.join(__dirname, "..");
require("../src/services/db").migrate();
const diagnostics = require("../src/services/production-diagnostics");

assert.deepEqual(Object.keys(diagnostics.CHECKS), [
  "system_health",
  "update_state",
  "plugins",
  "recent_errors",
  "benchmark"
]);

const key = "lumi_diag_verification-key_123";
const hash = diagnostics.hashAccessKey(key);
assert.match(hash, /^[a-f0-9]{64}$/);
assert.equal(diagnostics.verifyAccessKey(key, hash), true);
assert.equal(diagnostics.verifyAccessKey(`${key}x`, hash), false);
assert.equal(diagnostics.verifyAccessKey("wrong-prefix", hash), false);
assert.equal(diagnostics.isSecureDiagnosticRequest({ secure: true, ip: "203.0.113.10" }), true);
assert.equal(diagnostics.isSecureDiagnosticRequest({ secure: false, ip: "127.0.0.1" }), true);
assert.equal(diagnostics.isSecureDiagnosticRequest({ secure: false, ip: "203.0.113.10" }), false);
const proxiedRequest = {
  secure: false,
  protocol: "http",
  socket: { remoteAddress: "::ffff:172.19.0.4" },
  get(name) { return name === "x-forwarded-proto" ? "https" : ""; }
};
assert.equal(diagnostics.isTrustedPrivateProxyAddress("172.19.0.4"), true);
assert.equal(diagnostics.isTrustedPrivateProxyAddress("192.168.1.10"), true);
assert.equal(diagnostics.isTrustedPrivateProxyAddress("203.0.113.10"), false);
assert.equal(diagnostics.diagnosticsRequestProtocol(proxiedRequest), "https");
assert.equal(diagnostics.isSecureDiagnosticRequest(proxiedRequest), true);
assert.equal(diagnostics.diagnosticsRequestProtocol({ ...proxiedRequest, socket: { remoteAddress: "203.0.113.10" } }), "http");

const redacted = diagnostics.redactDiagnosticValue({
  token: "top-secret",
  message: `authorization=Bearer-value ${key} /mnt/c/private/lumi/file.js user@example.com ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh`,
  nested: { password: "also-secret", url: "https://example.test/?api_key=secret-value&ok=1" }
});
const redactedJson = JSON.stringify(redacted);
for (const forbidden of ["top-secret", "also-secret", key, "/mnt/c/private", "user@example.com", "secret-value", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh"]) {
  assert.equal(redactedJson.includes(forbidden), false, `diagnostic output leaked ${forbidden}`);
}
assert.match(redactedJson, /redacted|diagnostics key|local path|email/i);

const fingerprint = `verify-${Date.now()}`;
for (let index = 0; index < diagnostics.MAX_REQUESTS_PER_MINUTE; index += 1) {
  const rate = diagnostics.consumeRateLimit(fingerprint, 120000);
  assert.equal(rate.allowed, true);
}
assert.equal(diagnostics.consumeRateLimit(fingerprint, 120000).allowed, false);
assert.equal(diagnostics.consumeRateLimit(fingerprint, 180000).allowed, true);

for (const check of Object.keys(diagnostics.CHECKS)) {
  const result = diagnostics.runDiagnosticCheck(check);
  assert.equal(result.schema_version, 1);
  assert.equal(result.check, check);
  assert.equal(typeof result.duration_ms, "number");
  assert.doesNotMatch(JSON.stringify(result), /\blumi_diag_[A-Za-z0-9_-]+\b/);
}
assert.throws(() => diagnostics.runDiagnosticCheck("shell"), /Unknown diagnostic check/);

const serviceSource = fs.readFileSync(path.join(root, "src", "services", "production-diagnostics.js"), "utf8");
for (const forbidden of [
  /child_process/,
  /\bexec(?:Sync)?\s*\(/,
  /\bspawn(?:Sync)?\s*\(/,
  /\beval\s*\(/,
  /new\s+Function\s*\(/,
  /\bfetch\s*\(/,
  /require\(["'](?:https?|net|tls|dgram)["']\)/
]) {
  assert.doesNotMatch(serviceSource, forbidden, "diagnostics must not expose execution or network primitives");
}

const serverSource = fs.readFileSync(path.join(root, "src", "web", "server.js"), "utf8");
const endpointIndex = serverSource.indexOf('app.post("/api/diagnostics/v1/run"');
const configuredIndex = serverSource.indexOf("app.use(requireConfigured)");
assert(endpointIndex > 0 && endpointIndex < configuredIndex, "diagnostics endpoint must remain available for production recovery");
assert.match(serverSource, /authenticateDiagnosticsRequest\(req\)/);
assert.match(serverSource, /app\.set\("trust proxy", "loopback"\)/);
assert.match(serverSource, /app\.get\("\/admin\/diagnostics", requireRole\("admin"\)/);
assert.match(serverSource, /app\.post\("\/admin\/diagnostics\/access\/renew", requireRole\("admin"\)/);
assert.match(serverSource, /app\.post\("\/admin\/diagnostics\/access\/revoke", requireRole\("admin"\)/);

const viewSource = fs.readFileSync(path.join(root, "src", "web", "views", "admin-diagnostics.ejs"), "utf8");
assert.match(viewSource, /no remote control/i);
assert.match(viewSource, /data-confirm-mode="modal"/);
assert.match(viewSource, /\.secrets/);
assert.match(viewSource, /diagnosticsEndpointUrl/);
assert.match(viewSource, /diagnosticsBaseUrl/);
assert.doesNotMatch(viewSource, /https:\/\/your-lumi-host/);
assert.match(serverSource, /const diagnosticsBaseUrl = `\$\{diagnosticsRequestProtocol\(req\)\}:\/\/\$\{req\.get\("host"\)\}`/);

const clientSource = fs.readFileSync(path.join(root, "scripts", "production-diagnostics-client.js"), "utf8");
assert.match(clientSource, /path\.join\(root, "\.secrets"\)/);
assert.match(clientSource, /path\.join\(defaultSecretPath, "production-diagnostics\.json"\)/);
assert.match(clientSource, /method: "POST"/);
assert.match(clientSource, /new URL\("\/api\/diagnostics\/v1\/run"/);
assert.match(clientSource, /LUMI_PROD_URL/);
assert.match(clientSource, /LUMI_DIAG_KEY/);
assert.match(clientSource, /function parseConfig\(raw\)/);
assert.doesNotMatch(clientSource, /console\.(?:log|error)\(\s*key\s*\)/, "client must not print its access key");

console.log("Production diagnostics verification passed: fixed read-only checks, redaction, key validation, rate limiting, HTTPS proxy trust, and admin-only controls.");
