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

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

const UI_TIMEOUT_MS = Number(process.env.UI_TIMEOUT_MS || 10_000);

function chromiumExecutablePath() {
  return [
    process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || "",
    "/usr/bin/google-chrome-stable",
    "/usr/bin/google-chrome",
    "/snap/bin/chromium",
    "/usr/bin/chromium",
    "/usr/bin/chromium-browser",
  ].find((candidate) => candidate && fs.existsSync(candidate)) || undefined;
}

function startGateway(port) {
  return spawn("cargo", ["run", "-q", "-p", "mnote-web", "--bin", "mnote-web"], {
    cwd: "/mnt/Data1T/mnote/rust",
    env: {
      ...process.env,
      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_ENABLE_LEGACY_NEXT_COMPAT: "1",
      MNOTE_WEB_LEGACY_NEXT_BASE_URL: "http://127.0.0.1:3100",
    },
    stdio: ["ignore", "pipe", "pipe"],
  });
}

async function main() {
  let baseUrl = (process.env.MNOTE_UI_BASE_URL || "").replace(/\/+$/, "");
  let gateway = null;
  if (!baseUrl) {
    const port = await findFreePort();
    baseUrl = `http://127.0.0.1:${port}`;
    gateway = startGateway(port);
    await waitForGateway(baseUrl);
  }

  const executablePath = chromiumExecutablePath();
  const browser = await chromium.launch({
    headless: true,
    ...(executablePath ? { executablePath } : {}),
  });

  try {
    const authPage = await browser.newPage();
    await authPage.goto(`${baseUrl}/auth`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
    await authPage.locator('[data-testid="mnote-auth-page"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    assert(await authPage.locator('#account').isVisible(), "登录态应显示邮箱或用户名输入框");
    assert(!(await authPage.locator('#email').isVisible()), "登录态不应显示注册邮箱输入框");
    await authPage.locator('[data-auth-switch]').click();
    await authPage.locator('#email').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    assert(await authPage.locator('#username').isVisible(), "注册态应显示用户名输入框");
    assert(!(await authPage.locator('#account').isVisible()), "注册态不应显示登录账号输入框");
    await authPage.close();

    const userContext = await browser.newContext({
      extraHTTPHeaders: {
        "x-mnote-actor-id": "user_profile_smoke",
        "x-mnote-actor-type": "user",
      },
    });
    const userPage = await userContext.newPage();
    await userPage.goto(baseUrl, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
    await userPage.locator('[data-testid="mnote-account-menu-trigger"]').click();
    await userPage.locator('[data-testid="mnote-account-menu"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    await userPage.waitForFunction(() => {
      const link = document.querySelector('[data-testid="mnote-account-access-policy"]');
      return link && link.getAttribute("href") === "/user/access-policy";
    }, { timeout: UI_TIMEOUT_MS });
    await userPage.locator('[data-testid="mnote-account-profile"]').click();
    await userPage.locator('[data-testid="mnote-profile-dialog"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    const profileText = await userPage.locator('[data-testid="mnote-profile-dialog"]').innerText();
    assert(profileText.includes("user_profile_smoke"), "个人信息弹窗应显示完整用户 ID");

    await userPage.goto(`${baseUrl}/user/access-policy`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
    await userPage.locator('[data-testid="mnote-admin-access-policy-page"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    const userAccessText = await userPage.locator('[data-testid="mnote-admin-access-policy-page"]').innerText();
    assert(userAccessText.includes("分享管理"), "普通用户授权页应显示分享管理");
    assert(!userAccessText.includes("验证目录"), "普通用户授权页不应显示目录授权验证表单");
    await userContext.close();

    const adminContext = await browser.newContext({
      extraHTTPHeaders: {
        "x-mnote-actor-id": "admin_profile_smoke",
        "x-mnote-actor-type": "admin",
      },
    });
    const adminPage = await adminContext.newPage();
    await adminPage.goto(baseUrl, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
    await adminPage.locator('[data-testid="mnote-account-menu-trigger"]').click();
    await adminPage.locator('[data-testid="mnote-account-menu"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    await adminPage.waitForFunction(() => {
      const link = document.querySelector('[data-testid="mnote-account-access-policy"]');
      return link && link.getAttribute("href") === "/admin/access-policy";
    }, { timeout: UI_TIMEOUT_MS });
    await adminPage.goto(`${baseUrl}/admin/access-policy`, { waitUntil: "domcontentloaded", timeout: UI_TIMEOUT_MS });
    await adminPage.locator('[data-testid="mnote-admin-access-policy-page"]').waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    const adminAccessText = await adminPage.locator('[data-testid="mnote-admin-access-policy-page"]').innerText();
    assert(adminAccessText.includes("目录授权"), "管理员授权页应显示目录授权");
    assert(adminAccessText.includes("分享管理"), "管理员授权页应显示分享管理");
    assert(await adminPage.locator('[data-testid="mnote-admin-validate-root-submit"]').isVisible(), "管理员页应显示验证目录按钮");
    await adminContext.close();

    console.log(JSON.stringify({ ok: true, task: "task489-auth-profile-access-ui", baseUrl }, null, 2));
  } finally {
    await browser.close().catch(() => {});
    if (gateway) {
      gateway.kill("SIGTERM");
      setTimeout(() => gateway.kill("SIGKILL"), 2_000).unref();
    }
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
