#!/usr/bin/env node
"use strict";

const assert = require("node:assert");
const { spawn } = require("node:child_process");
const {
  fetchWithTimeout,
  findFreePort,
  waitForGateway,
} = require("./task114-rust-web-gateway-entry-smoke.js");

function buildFixtureEnv(port) {
  return {
    MNOTE_WEB_ALLOW_DEV_FIXTURES: "1",
    MNOTE_WEB_BIND: `127.0.0.1:${port}`,
    MNOTE_WEB_PUBLIC_BIND: "127.0.0.1:3000",
    MNOTE_WEB_LEGACY_NEXT_BASE_URL: "http://127.0.0.1:3100",
    MNOTE_WEB_ENABLE_LEGACY_NEXT_COMPAT: "1",
    MNOTE_WEB_QUERY_FIXTURES_JSON: JSON.stringify({
      "documents:getMeta": {
        id: "doc_auth",
        workspace_id: "ws_demo",
        title: "认证验收页面",
        updated_at: "2026-05-04T00:00:00Z",
        can_edit: true,
        word_count: 3,
        character_count: 12,
        block_count: 1,
      },
      "documents:getContent": {
        content: [{ id: "block_auth_1", type: "paragraph", content: [] }],
        revision: 1,
        conflict_detection_key: "doc_auth:1",
        pageSubtree: { rootNodeId: "doc_auth", outline: [] },
      },
    }),
    MNOTE_WEB_MUTATION_FIXTURES_JSON: JSON.stringify({
      "workspaces:ensureDefaultWorkspace": {
        workspaces: [{ id: "ws_demo", name: "我的空间", type: "personal", memberCount: 1, isDefault: true }],
        activeWorkspaceId: "ws_demo",
      },
    }),
  };
}

function startGateway(port) {
  return spawn("cargo", ["run", "-q", "-p", "mnote-web", "--bin", "mnote-web"], {
    cwd: "/mnt/Data1T/mnote/rust",
    env: { ...process.env, ...buildFixtureEnv(port) },
    stdio: ["ignore", "pipe", "pipe"],
  });
}

async function validateAuthEntry(baseUrl) {
  const root = await fetchWithTimeout(`${baseUrl}/`);
  const rootText = await root.text();
  assert.equal(root.status, 303, `/ 未登录应跳转 /auth: ${root.status} ${rootText.slice(0, 160)}`);
  assert.equal(root.headers.get("location"), "/auth");
  assert.equal(root.headers.get("x-mnote-web-owner"), "mnote-web");

  const auth = await fetchWithTimeout(`${baseUrl}/auth`);
  const authText = await auth.text();
  assert.equal(auth.status, 200, `/auth 请求失败: ${auth.status}`);
  assert.equal(auth.headers.get("x-mnote-web-owner"), "mnote-web");
  assert.equal(auth.headers.get("x-mnote-legacy-upstream"), null, "/auth 不应代理到 3100");
  assert.match(authText, /data-mnote-shell="auth"/);
  assert.match(authText, /data-testid="mnote-auth-page"/);
  assert.match(authText, /账号登录/);
  assert.match(authText, /邮箱或用户名/);
  assert.match(authText, /name="account"[^>]*type="text"|type="text"[^>]*name="account"/);
  assert.doesNotMatch(authText, /name="username"/);
  assert.match(authText, /name="password"[^>]*type="password"|type="password"[^>]*name="password"/);
  assert.match(authText, /data-auth-mode="convex-password"/);
  assert.match(authText, /没有账号？注册/);
  assert.match(authText, /测试账号快速登录/);
  assert.doesNotMatch(authText, /隐私政策|使用\s*Google|使用\s*GitHub|第三方快捷/iu);

  const authedAuth = await fetchWithTimeout(`${baseUrl}/auth`, {
    headers: {
      "x-mnote-actor-id": "user_real",
      "x-mnote-actor-type": "user",
    },
  });
  assert.equal(authedAuth.status, 303, `/auth 已登录应跳转 /: ${authedAuth.status}`);
  assert.equal(authedAuth.headers.get("location"), "/");

  const authedRoot = await fetchWithTimeout(`${baseUrl}/`, {
    headers: {
      "x-mnote-actor-id": "user_real",
      "x-mnote-actor-type": "user",
    },
  });
  const authedRootText = await authedRoot.text();
  assert.equal(authedRoot.status, 200, `/ 已登录根入口失败: ${authedRoot.status}`);
  assert.match(authedRootText, /data-mnote-shell="workspace"/);
}

async function main() {
  const external = (process.env.MNOTE_UI_BASE_URL || "").replace(/\/+$/, "");
  let gateway = null;
  let baseUrl = external;

  if (!baseUrl) {
    const port = await findFreePort();
    baseUrl = `http://127.0.0.1:${port}`;
    gateway = startGateway(port);
    await waitForGateway(baseUrl);
  }

  let stderr = "";
  if (gateway) {
    gateway.stderr.on("data", (chunk) => {
      stderr += chunk.toString("utf8");
    });
  }

  try {
    await validateAuthEntry(baseUrl);
    console.log(JSON.stringify({ ok: true, baseUrl, task: "task159-auth-entry" }, null, 2));
  } finally {
    if (gateway) {
      gateway.kill("SIGTERM");
      setTimeout(() => gateway.kill("SIGKILL"), 2_000).unref();
      if (stderr.trim()) {
        process.stderr.write(stderr.slice(-2000));
      }
    }
  }
}

if (require.main === module) {
  main().catch((error) => {
    console.error(error);
    process.exit(1);
  });
}
