import assert from "node:assert/strict";
import { createHash, generateKeyPairSync } from "node:crypto";
import { readFile, readdir } from "node:fs/promises";
import test from "node:test";

import { createEntitlementSigner } from "../apps/entitlement-verifier/src/entitlement-signer.js";
import { createGooglePlayClient } from "../apps/entitlement-verifier/src/google-play.js";
import { publicErrorResponse } from "../apps/entitlement-verifier/src/http.js";
import { createPurchaseStateStore } from "../apps/entitlement-verifier/src/purchase-state.js";
import { createRtdnRoute } from "../apps/entitlement-verifier/src/rtdn.js";
import { createVerifyPurchaseRoute, createVerificationRateLimiter } from "../apps/entitlement-verifier/src/verify-purchase.js";

const APP = new URL("../apps/entitlement-verifier/", import.meta.url);
const PACKAGE_NAME = "com.makecdev.coderemotemanager";
const PRODUCT_ID = "pro_multi_account";
const PURCHASE_TOKEN = "fake-release-purchase-token-12345";
const NOW = Date.UTC(2026, 7, 2, 12, 0, 0);

test("verifier container is pinned, non-root, health-checked, and production-only", async () => {
  const dockerfile = await text("Dockerfile");
  const dockerignore = await text(".dockerignore");
  const packageLock = JSON.parse(await text("package-lock.json"));

  assert.match(dockerfile, /^FROM node:22\.17\.0-bookworm-slim$/m);
  assert.doesNotMatch(dockerfile, /^FROM node:(?:latest|22|22-bookworm|22-bookworm-slim)$/m);
  assert.match(dockerfile, /npm ci --omit=dev --ignore-scripts/);
  assert.match(dockerfile, /^USER node$/m);
  assert.match(dockerfile, /^HEALTHCHECK /m);
  assert.match(dockerfile, /^CMD \["node",\s*"src\/server\.js"\]$/m);
  assert.doesNotMatch(dockerfile, /^COPY\s+\.\s+/m);
  for (const required of ["**", "!package.json", "!package-lock.json", "!src/", "!src/**/*.js", "src/**/*.test.js"]) {
    assert.equal(dockerignore.split(/\r?\n/).includes(required), true, `missing dockerignore rule: ${required}`);
  }
  assert.equal(packageLock.packages[""].name, "@code-remote-manager/entitlement-verifier");
  assert.equal(packageLock.packages[""].dependencies["google-auth-library"], "11.0.0");
  assert.equal(packageLock.packages[""].dependencies["@google-cloud/firestore"], "8.7.0");
});

test("container production context and source contain no credential or purchase fixtures", async () => {
  const sourceNames = (await readdir(new URL("src/", APP))).filter((name) => name.endsWith(".js") && !name.endsWith(".test.js"));
  const source = (await Promise.all(sourceNames.map((name) => text(`src/${name}`)))).join("\n");
  const containerContext = [await text("package.json"), await text("package-lock.json"), source].join("\n");

  for (const forbidden of [
    /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/,
    /"type"\s*:\s*"service_account"/,
    /"private_key"\s*:/,
    /"client_email"\s*:/,
    /fake-release-purchase-token/,
    /purchase-token-123/,
    /GOOGLE_APPLICATION_CREDENTIALS\s*=/,
  ]) assert.doesNotMatch(containerContext, forbidden);
  assert.doesNotMatch(source, /console\.(?:log|warn|error)\s*\(/);
  assert.doesNotMatch(source, /JSON\.stringify\s*\(\s*(?:req|request|error|headers)\b/);
});

test("release identity stays fixed across verifier production modules", async () => {
  const sourceNames = (await readdir(new URL("src/", APP))).filter((name) => name.endsWith(".js") && !name.endsWith(".test.js"));
  const sources = await Promise.all(sourceNames.map(async (name) => [name, await text(`src/${name}`)]));
  const identityModules = sources.filter(([, source]) => source.includes("const PACKAGE_NAME"));
  assert.ok(identityModules.length >= 4);
  for (const [name, source] of identityModules) {
    assert.match(source, new RegExp(`const PACKAGE_NAME = "${PACKAGE_NAME.replaceAll(".", "\\.")}";`), name);
    if (source.includes("const PRODUCT_ID")) assert.match(source, new RegExp(`const PRODUCT_ID = "${PRODUCT_ID}";`), name);
  }
});

test("fake Google E2E verifies, acknowledges, restores, invalidates, and denies later issuance", async () => {
  const memory = fakeFirestore();
  const purchaseStore = createPurchaseStateStore({ firestore: memory.firestore, now: () => NOW });
  let acknowledged = false;
  let acknowledgementCalls = 0;
  const googlePlay = createGooglePlayClient({
    auth: { async getRequestHeaders() { return { authorization: "Bearer fake-adc" }; } },
    fetch: async (url, options) => {
      if (url.endsWith(":acknowledge")) {
        acknowledgementCalls += 1;
        acknowledged = true;
        return jsonResponse({});
      }
      assert.equal(options.method, "GET");
      return jsonResponse(purchasedGoogleState(acknowledged));
    },
    packageName: PACKAGE_NAME,
    productId: PRODUCT_ID,
  });
  const privateKey = generateKeyPairSync("ed25519").privateKey.export({ format: "pem", type: "pkcs8" });
  const signer = createEntitlementSigner({
    privateKey,
    keyId: "release-gate",
    issuer: "https://entitlements.example.com",
    now: () => NOW,
    randomUUID: () => "11111111-2222-4333-8444-555555555555",
  });
  const verify = createVerifyPurchaseRoute({
    googlePlay,
    purchaseStore,
    signer,
    rateLimiter: createVerificationRateLimiter({ now: () => NOW, tokenLimit: 10 }),
    packageName: PACKAGE_NAME,
    productId: PRODUCT_ID,
  });

  const first = await invokeVerification(verify);
  const restored = await invokeVerification(verify);
  assert.equal(first.status, 200);
  assert.equal(restored.status, 200);
  assert.equal(acknowledgementCalls, 1);
  assert.equal(first.body.certificate, restored.body.certificate);

  const rtdn = createRtdnRoute({
    oidc: { async verifyRequest() {} },
    purchaseStore,
    messageStore: { async record() { return { duplicate: false }; } },
    config: {
      packageName: PACKAGE_NAME,
      productId: PRODUCT_ID,
      pubsubOidc: { audience: "https://entitlements.example.com/internal/google-play/rtdn", serviceAccounts: ["push@example.iam.gserviceaccount.com"] },
    },
  });
  await rtdn({
    req: { method: "POST", headers: { authorization: "Bearer fake" } },
    url: new URL("https://entitlements.example.com/internal/google-play/rtdn"),
    readJson: async () => pubsubCancellation(),
  });

  await assert.rejects(invokeVerification(verify), (error) => {
    assert.deepEqual(publicErrorResponse(error), { status: 402, code: "purchase_invalidated" });
    return true;
  });
  const serialized = JSON.stringify([...memory.docs]);
  assert.equal(serialized.includes(PURCHASE_TOKEN), false);
  assert.equal(serialized.includes(createHash("sha256").update(PURCHASE_TOKEN).digest("hex")), false);
});

function text(relativePath) {
  return readFile(new URL(relativePath, APP), "utf8");
}

function invokeVerification(route) {
  return route({
    req: { method: "POST" },
    url: new URL("https://entitlements.example.com/v1/entitlements/google-play/verify"),
    clientIp: "127.0.0.1",
    readJson: async () => ({
      purchaseToken: PURCHASE_TOKEN,
      backendKeyThumbprint: "a".repeat(43),
      challengeHash: "b".repeat(43),
    }),
  });
}

function purchasedGoogleState(isAcknowledged) {
  return {
    purchaseStateContext: { purchaseState: "PURCHASED" },
    productLineItem: [{
      productId: PRODUCT_ID,
      productOfferDetails: {
        quantity: 1,
        refundableQuantity: 1,
        consumptionState: "CONSUMPTION_STATE_YET_TO_BE_CONSUMED",
      },
    }],
    acknowledgementState: isAcknowledged
      ? "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED"
      : "ACKNOWLEDGEMENT_STATE_PENDING",
    purchaseCompletionTime: "2026-08-02T11:55:00Z",
  };
}

function pubsubCancellation() {
  const notification = {
    version: "1.0",
    packageName: PACKAGE_NAME,
    eventTimeMillis: String(NOW),
    oneTimeProductNotification: { version: "1.0", notificationType: 2, purchaseToken: PURCHASE_TOKEN, sku: PRODUCT_ID },
  };
  return {
    message: { messageId: "release-event-1", data: Buffer.from(JSON.stringify(notification)).toString("base64") },
    subscription: "projects/fake/subscriptions/play-events",
  };
}

function jsonResponse(body) {
  return { ok: true, status: 200, async json() { return structuredClone(body); } };
}

function fakeFirestore() {
  const docs = new Map();
  let queue = Promise.resolve();
  const firestore = {
    collection(name) { return { doc(id) { return { path: `${name}/${id}` }; } }; },
    runTransaction(operation) {
      const run = queue.then(async () => {
        const writes = [];
        const result = await operation({
          async get(ref) { const value = docs.get(ref.path); return { exists: value !== undefined, data: () => structuredClone(value) }; },
          set(ref, value) { writes.push([ref.path, structuredClone(value)]); },
        });
        for (const [path, value] of writes) docs.set(path, value);
        return result;
      });
      queue = run.catch(() => {});
      return run;
    },
  };
  return { docs, firestore };
}
