import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { readFile } from "node:fs/promises";
import test from "node:test";
import { promisify } from "node:util";

const execFileAsync = promisify(execFile);
const root = new URL("../", import.meta.url);
const PACKAGE_NAME = "com.makecdev.coderemotemanager";
const PRODUCT_ID = "pro_multi_account";

test("tracked Pro release inputs contain no credentials, private paths, debug origins, or raw purchase tokens", async () => {
  const tracked = await trackedReleaseInputs();
  const forbiddenNames = tracked.filter((path) =>
    /(?:^|\/)(?:auth\.json|google-services\.json|service-account[^/]*\.json|[^/]+\.(?:jks|keystore|p12|pem))$/i.test(path),
  );
  assert.deepEqual(forbiddenNames, []);

  const patterns = [
    ["private key", /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/],
    ["service account JSON", /"type"\s*:\s*"service_account"|"private_key"\s*:|"client_email"\s*:/],
    ["local Windows path", /[A-Za-z]:\\(?:Users|Project)\\/],
    ["local Unix path", /\/(?:Users|home)\/[^/\s"']+\//],
    ["debug verifier origin", /https?:\/\/(?:localhost|127\.0\.0\.1|10\.0\.2\.2)(?::\d+)?/, (path) => !path.endsWith("/Dockerfile")],
    ["raw purchase token", /(?:PURCHASE_TOKEN|purchaseToken)\s*[:=]\s*["'][^"']+["']/],
  ];

  for (const path of tracked.filter(isTextReleaseInput)) {
    const source = await readFile(new URL(path, root), "utf8");
    for (const [label, pattern, applies = () => true] of patterns) {
      if (applies(path)) assert.doesNotMatch(source, pattern, `${path}: ${label}`);
    }
  }
});

test("tracked Pro release inputs use one package and product identity", async () => {
  const tracked = (await trackedReleaseInputs()).filter(isTextReleaseInput);
  const sources = await Promise.all(tracked.map((path) => readFile(new URL(path, root), "utf8")));
  const packageNames = new Set(sources.flatMap((source) => source.match(/com\.[A-Za-z0-9_.-]*coderemotemanager\b/g) ?? []));
  const productIds = new Set(sources.flatMap((source) => [...source.matchAll(
    /(?:PRODUCT_ID\s*=\s*|productId\s*:\s*|ProductResult\(\s*)["'](pro_[a-z0-9_]+)["']/g,
  )].map((match) => match[1])));

  assert.deepEqual([...packageNames].sort(), [PACKAGE_NAME]);
  assert.deepEqual([...productIds].sort(), [PRODUCT_ID]);
});

test("distribution notice records shipped Pro dependency versions, licenses, and sources", async () => {
  const notice = await readFile(new URL("distribution/THIRD_PARTY_NOTICES.txt", root), "utf8");

  assert.match(notice, /Google Play Billing Library 9\.1\.0[\s\S]*Android Software Development Kit License[\s\S]*https:\/\/maven\.google\.com\/web\/index\.html#com\.android\.billingclient:billing:9\.1\.0/);
  assert.match(notice, /Google Auth Library 11\.0\.0[\s\S]*Apache-2\.0[\s\S]*https:\/\/github\.com\/googleapis\/google-cloud-node\/tree\/main\/core\/packages\/google-auth-library-nodejs/);
  assert.match(notice, /Google Cloud Firestore Client 8\.7\.0[\s\S]*Apache-2\.0[\s\S]*https:\/\/github\.com\/googleapis\/google-cloud-node\/tree\/main\/handwritten\/firestore/);
});

async function trackedReleaseInputs() {
  const { stdout } = await execFileAsync("git", [
    "ls-files", "--", "apps/entitlement-verifier", "apps/pwa/android", "apps/pwa/src", "apps/pwa/index.html",
    "apps/pwa/public", "distribution/THIRD_PARTY_NOTICES.txt",
  ]);
  return stdout.split(/\r?\n/).filter(Boolean).map((path) => path.replaceAll("\\", "/"));
}

function isTextReleaseInput(path) {
  if (/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(path) || path.includes("/src/test/") || path.includes("/src/androidTest/")) return false;
  return /(?:Dockerfile|\.dockerignore|package(?:-lock)?\.json|\.gradle|\.properties|\.pro|\.html|\.xml|\.java|\.jsx?|\.css|\.txt)$/.test(path);
}
