"use strict";

const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { createApp } = require("./server");
const { authorizeRepoPush } = require("./authorize-repo-push");

test("repo-push helper stops with a server receipt when no safe transport is deployed", async () => {
  const mail = [];
  const directory = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-repo-push-"));
  const mapGate = {
    read: target => ({ hash: `map-${target}`, data: { node_id: target } }),
    ack: () => ({ ok: true }),
    verify: () => ({ ok: true }),
  };
  const app = createApp({
    ownerEmail: "owner@example.invalid",
    publicBaseUrl: "https://example.invalid/authz",
    targets: ["JD-FD-PRIMARY"],
    stateFile: "",
    repoGrantDir: directory,
    mapGate,
    sendEmail: async message => { mail.push(message); return true; },
  });
  await new Promise(resolve => app.listen(0, "127.0.0.1", resolve));
  const base = `http://127.0.0.1:${app.address().port}`;
  const lines = [];
  try {
    const grantPromise = authorizeRepoPush({
      url: base,
      persona: "ICE-GL-ZY001",
      name: "铸渊",
      repo: "bingshuo/fifth-domain",
      poll: 1,
    }, {
      output: line => lines.push(line),
      sleep: milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds)),
    });

    while (!lines.some(line => line.startsWith("REQUEST_URL="))) await new Promise(resolve => setTimeout(resolve, 1));
    const requestUrl = lines.find(line => line.startsWith("REQUEST_URL=")).slice("REQUEST_URL=".length);
    const requestPath = new URL(requestUrl).pathname.replace("/authz", "");
    assert.equal((await fetch(`${base}${requestPath}`, { method: "POST" })).status, 200);
    assert.equal(mail.length, 1);
    const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
    assert.equal((await fetch(`${base}${approvalPath}`, { method: "POST" })).status, 200);

    await assert.rejects(grantPromise, /repo_push_transport_unavailable/);
    assert.ok(lines.some(line => line.startsWith("[LL-REPO-PUSH-TRANSPORT-BLOCKED]")));
    assert.ok(fs.existsSync(path.join(directory, "bingshuo__fifth-domain.json")));
  } finally {
    await new Promise(resolve => app.close(resolve));
    fs.rmSync(directory, { recursive: true, force: true });
  }
});
