/**
 * VERIFY BAR — client-IP resolver + fail-closed trust-proxy default.
 *
 * Both directions, no platform boot: a tiny express app exercising the SHIPPED resolver
 * (rate-limiter.getClientIp) under the two trust-proxy settings.
 *
 *   trust proxy = 0 (the fix / fail-closed default): a forged X-Forwarded-For MUST be ignored —
 *     getClientIp returns the real socket peer, not the client's claim. This is what closes both
 *     the audit-attribution spoof and the `X-Forwarded-For: 127.0.0.1` anomaly-scoring bypass.
 *   trust proxy = 1 (CONTROL): with one hop trusted, the header IS honoured — proving the test is
 *     real (the resolver isn't just always-returning-peer) and that a proxied deployment that
 *     declares its hop count still gets the true client IP.
 *
 * A forged value of 1.2.3.4 is used precisely because it can never coincide with the loopback peer,
 * so "ignored" vs "honoured" is unambiguous.
 */
import express from "express";
import http from "http";
import { getClientIp, resolveTrustProxyHops } from "../server/lib/rate-limiter";

function makeServer(hops: number): Promise<http.Server> {
  const app = express();
  app.set("trust proxy", hops === 0 ? false : hops);
  app.get("/whoami", (req, res) => res.json({ ip: getClientIp(req) }));
  return new Promise((resolve) => {
    const s = app.listen(0, "127.0.0.1", () => resolve(s));
  });
}

function whoami(port: number, xff?: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const r = http.get(
      { host: "127.0.0.1", port, path: "/whoami", headers: xff ? { "x-forwarded-for": xff } : {} },
      (res) => { let d = ""; res.on("data", (c) => (d += c)); res.on("end", () => resolve(JSON.parse(d).ip)); },
    );
    r.on("error", reject);
  });
}

const isLoopback = (ip: string) => ip === "127.0.0.1" || ip === "::1" || ip === "::ffff:127.0.0.1";

async function main() {
  const s0 = await makeServer(0); // the fix
  const s1 = await makeServer(1); // control
  const p0 = (s0.address() as any).port, p1 = (s1.address() as any).port;

  const checks = {
    // the code default (no env) must now be fail-closed
    default_is_0: resolveTrustProxyHops(undefined) === 0,
    // trust proxy 0: forged header ignored -> real peer, NOT the claim
    hops0_no_header: await whoami(p0),
    hops0_forged: await whoami(p0, "1.2.3.4"),
    // control: trust proxy 1 honours the declared hop -> the claim wins
    hops1_forged: await whoami(p1, "1.2.3.4"),
  };

  const pass =
    checks.default_is_0 &&
    isLoopback(checks.hops0_no_header) &&
    isLoopback(checks.hops0_forged) &&        // FIX: forged header discarded, real peer recorded
    checks.hops0_forged !== "1.2.3.4" &&
    checks.hops1_forged === "1.2.3.4";        // CONTROL: honoured with a trusted hop (test is real)

  console.log(JSON.stringify({ pass, checks }));
  s0.close(); s1.close();
  process.exit(pass ? 0 : 1);
}

main().catch((e) => { console.error("VERIFY ERROR:", e?.message || e); process.exit(2); });
