import test from "node:test";
import assert from "node:assert/strict";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
import { tmpdir } from "node:os";
import { completeAccountLogin, createAccount, listPublicAccounts, persistCreatedAccount, pruneUnauthenticatedManagedAccounts, removeAccount, removeAllAccounts, restoreLocalHistorySources, startAccountLogin, updateAccountLabel } from "./accounts.js";
import { assertCanAddExecutionAccount } from "./entitlement-policy.js";
import { loadConfig } from "./config.js";

test("desktop codex account is hidden until authenticated when historyOnly is omitted", async () => {
  const result = await listPublicAccounts({ accounts: [
    { id: "desktop-codex", label: "Desktop Codex", codexHome: "missing-desktop" }
  ] });

  assert.deepEqual(result, []);
});

test("logged-out managed account remains visible as needing login", async () => {
  const dataDir = resolve(await mkdtemp(join(tmpdir(), "crm-accounts-")), "runtime");
  const account = {
    id: "managed-a",
    label: "Personal",
    codexHome: resolve(dirname(dataDir), "accounts", "managed-a", "codex-home")
  };

  const accounts = await listPublicAccounts({ codexCliPath: "codex", dataDir, accounts: [account] });

  assert.deepEqual(accounts, [{ id: "managed-a", label: "Personal", status: "needs_login" }]);
});

test("public account projection preserves every visible ID even when emails match", async () => {
  const firstHome = await authenticatedHome();
  const secondHome = await authenticatedHome();
  try {
    const accounts = await listPublicAccounts({ accounts: [
      { id: "desktop", label: "Desktop", codexHome: firstHome },
      { id: "managed", label: "Managed", codexHome: secondHome }
    ] }, async () => ({ account: { type: "chatgpt", email: "person@example.com" } }));

    assert.deepEqual(accounts.map(({ id, email }) => ({ id, email })), [
      { id: "desktop", email: "person@example.com" },
      { id: "managed", email: "person@example.com" }
    ]);
  } finally {
    await Promise.all([
      rm(firstHome, { recursive: true, force: true }),
      rm(secondHome, { recursive: true, force: true })
    ]);
  }
});

test("starts login only for the selected visible account", async () => {
  const config = {
    codexCliPath: "codex.cmd",
    accounts: [
      { id: "a", label: "A", codexHome: "C:\\Accounts\\a" },
      { id: "desktop", label: "Desktop", codexHome: "C:\\Desktop", historyOnly: true }
    ]
  };
  let input;
  let createdDirectory;

  const result = await startAccountLogin(config, "a", async (value) => {
    input = value;
    return { loginId: "login-1", verificationUrl: "https://example.com/device", userCode: "ABCD" };
  }, async (path) => { createdDirectory = path; });

  assert.equal(input.codexCliPath, "codex.cmd");
  assert.equal(input.codexHome, "C:\\Accounts\\a");
  assert.equal(createdDirectory, "C:\\Accounts\\a");
  assert.deepEqual(result, { loginId: "login-1", verificationUrl: "https://example.com/device", userCode: "ABCD" });
  await assert.rejects(startAccountLogin(config, "desktop", async () => ({})), (error) => error.message === "account_not_found");
});

test("completing login preserves configured accounts that share an authenticated identity", async () => {
  const config = { accounts: [
    { id: "existing", label: "Existing", codexHome: "existing-home" },
    { id: "new", label: "New account", codexHome: "new-home" }
  ] };
  const projections = [
    { id: "existing", email: "Person@Example.com", status: "logged_in" },
    { id: "new", email: " person@example.com ", status: "logged_in" }
  ];

  const result = await completeAccountLogin(config, "config.local.json", "new", {
    listAccounts: async (nextConfig) => nextConfig.accounts.map((account) => projections.find((item) => item.id === account.id)),
    persistConfig: async () => assert.fail("login completion must not rewrite configured account IDs")
  });

  assert.deepEqual(result, {
    connected: true,
    deduplicated: false,
    accounts: projections
  });
  assert.deepEqual(config.accounts.map((account) => account.id), ["existing", "new"]);
});

test("removing all accounts keeps every local store as hidden history", async () => {
  const config = { accounts: [
    { id: "managed", label: "Managed", codexHome: "managed-home" },
    { id: "desktop-codex", label: "Desktop Codex", codexHome: "desktop-home" },
    { id: "old-history", label: "Old history", codexHome: "history-home", historyOnly: true }
  ] };
  let persisted;

  const result = await removeAllAccounts(config, "config.local.json", {
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; }
  });

  assert.deepEqual(result, { accounts: [] });
  assert.deepEqual(config.accounts, [
    { id: "managed", label: "Managed", codexHome: "managed-home", historyOnly: true },
    { id: "desktop-codex", label: "Desktop Codex", codexHome: "desktop-home", historyOnly: true },
    { id: "old-history", label: "Old history", codexHome: "history-home", historyOnly: true }
  ]);
  assert.deepEqual(persisted.accounts, config.accounts);
});

test("startup restores unconfigured managed stores that still contain local history", async () => {
  const root = await mkdtemp(join(tmpdir(), "code-remote-manager-account-"));
  const configPath = join(root, "config.local.json");
  const configuredHome = join(root, "accounts", "configured", "codex-home");
  const orphanHome = join(root, "accounts", "orphan-account", "codex-home");
  const emptyHome = join(root, "accounts", "empty-account", "codex-home");
  const config = {
    dataDir: join(root, "data"),
    accounts: [{ id: "configured", label: "Configured", codexHome: configuredHome }]
  };
  await Promise.all([
    mkdir(join(orphanHome, "sessions", "2026", "07", "18"), { recursive: true }),
    mkdir(emptyHome, { recursive: true })
  ]);
  await writeFile(join(orphanHome, "sessions", "2026", "07", "18", "rollout.jsonl"), "{}\n");
  let persisted;

  try {
    const result = await restoreLocalHistorySources(config, configPath, {
      desktopCodexHome: join(root, "empty-desktop-home"),
      persistConfig: async (_path, nextConfig) => { persisted = nextConfig; }
    });

    assert.equal(result.restored, 1);
    assert.deepEqual(config.accounts.map(({ id, label, historyOnly }) => ({ id, label, historyOnly })), [
      { id: "configured", label: "Configured", historyOnly: undefined },
      { id: "orphan-account", label: "Saved history", historyOnly: true }
    ]);
    assert.deepEqual(persisted.accounts, config.accounts);
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});

test("startup restores trusted Desktop Codex history outside the managed account root", async () => {
  const root = await mkdtemp(join(tmpdir(), "code-remote-manager-account-"));
  const configPath = join(root, "config.local.json");
  const desktopCodexHome = join(root, "desktop-codex-home");
  const config = { dataDir: join(root, "data"), accounts: [] };
  await mkdir(join(desktopCodexHome, "sessions", "2026", "07", "18"), { recursive: true });
  await writeFile(join(desktopCodexHome, "sessions", "2026", "07", "18", "rollout.jsonl"), "{}\n");
  let persisted;

  try {
    const result = await restoreLocalHistorySources(config, configPath, {
      desktopCodexHome,
      persistConfig: async (_path, nextConfig) => { persisted = nextConfig; }
    });

    assert.equal(result.restored, 1);
    assert.deepEqual(config.accounts, [{
      id: "desktop-codex",
      label: "Desktop Codex history",
      codexHome: desktopCodexHome,
      historyOnly: true
    }]);
    assert.deepEqual(persisted.accounts, config.accounts);
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});

test("completing login keeps a distinct authenticated account", async () => {
  const config = { accounts: [
    { id: "existing", label: "Existing", codexHome: "existing-home" },
    { id: "new", label: "New account", codexHome: "new-home" }
  ] };

  const result = await completeAccountLogin(config, "config.local.json", "new", {
    listAccounts: async () => [
      { id: "existing", email: "first@example.com", status: "logged_in" },
      { id: "new", email: "second@example.com", status: "logged_in" }
    ],
    persistConfig: async () => assert.fail("distinct account must not rewrite config")
  });

  assert.equal(result.connected, true);
  assert.equal(result.deduplicated, false);
  assert.equal(result.existingAccountId, undefined);
  assert.deepEqual(config.accounts.map((account) => account.id), ["existing", "new"]);
});

test("completing login waits while authentication is incomplete", async () => {
  const config = { accounts: [{ id: "new", label: "New account", codexHome: "new-home" }] };
  const accounts = [{ id: "new", label: "New account", status: "needs_login" }];

  const result = await completeAccountLogin(config, "config.local.json", "new", {
    listAccounts: async () => accounts,
    persistConfig: async () => assert.fail("incomplete login must not rewrite config")
  });

  assert.deepEqual(result, { connected: false, deduplicated: false, accounts });
});

test("completing login rejects an authenticated account without a safe identity", async () => {
  const config = { accounts: [{ id: "new", label: "New account", codexHome: "new-home" }] };

  await assert.rejects(
    completeAccountLogin(config, "config.local.json", "new", {
      listAccounts: async () => [{ id: "new", label: "New account", status: "logged_in" }],
      persistConfig: async () => assert.fail("missing identity must not rewrite config")
    }),
    (error) => error.message === "account_identity_unavailable" && error.status === 409
  );
});

test("turns device-code rate limits into a safe public error", async () => {
  const config = { codexCliPath: "codex.cmd", accounts: [{ id: "a", label: "A", codexHome: "C:\\Accounts\\a" }] };

  await assert.rejects(
    startAccountLogin(config, "a", async () => { throw new Error("device code failed with 429 Too Many Requests at C:\\secret"); }, async () => {}),
    (error) => error.message === "account_login_rate_limited" && error.status === 429
  );
});

test("history-only source stays out of public account selector", async () => {
  const result = await listPublicAccounts({ accounts: [
    { id: "a", label: "A", codexHome: "missing-a" },
    { id: "desktop", label: "Desktop", codexHome: "missing-desktop", historyOnly: true }
  ] });
  assert.deepEqual(result, []);
});

test("public accounts show auth email without exposing credentials or paths", async () => {
  const codexHome = await mkdtemp(join(tmpdir(), "code-remote-manager-account-"));
  await writeFile(join(codexHome, "auth.json"), JSON.stringify({
    OPENAI_ACCOUNT_EMAIL: "person@example.com",
    access_token: "secret-access-token",
    refresh_token: "secret-refresh-token"
  }));

  let request;
  const result = await listPublicAccounts({ codexCliPath: "codex.cmd", accounts: [
    { id: "a", label: "Account A", codexHome }
  ] }, async (input) => {
    request = input;
    return { requiresOpenaiAuth: true, account: { type: "chatgpt", email: "person@example.com", planType: "plus" } };
  });

  assert.deepEqual(result, [{
    id: "a",
    label: "Account A",
    email: "person@example.com",
    displayName: "person@example.com",
    planType: "plus",
    status: "logged_in"
  }]);
  assert.equal(request.method, "account/read");
  assert.deepEqual(request.params, { refreshToken: false });
  assert.equal(request.codexHome, codexHome);
  const serialized = JSON.stringify(result);
  assert.equal(serialized.includes("secret-access-token"), false);
  assert.equal(serialized.includes("secret-refresh-token"), false);
  assert.equal(serialized.includes(codexHome), false);
});

test("creates a managed visible account and persists before mutating live config", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: []
  };
  let persisted;
  let createdDirectory;

  const result = await createAccount(config, "config.local.json", { label: "  Work Account  " }, {
    randomUUID: () => "abcdef12-3456-7890-abcd-ef1234567890",
    makeDirectory: async (path) => { createdDirectory = path; },
    persistConfig: async (_path, nextConfig) => {
      assert.equal(config.accounts.length, 0);
      persisted = nextConfig;
    }
  });

  assert.equal(result.account.id, "work-account-abcdef12");
  assert.equal(result.account.label, "Work Account");
  assert.equal(result.account.status, "needs_login");
  assert.deepEqual(result.accounts, [result.account]);
  assert.match(persisted.accounts[0].codexHome, /accounts[\\/]work-account-abcdef12[\\/]codex-home$/);
  assert.equal(createdDirectory, persisted.accounts[0].codexHome);
  assert.equal(config.accounts.length, 1);
});

test("creates a login-ready account without asking for an email label", async () => {
  const config = { dataDir: "C:\\CodeRemoteManager\\data", accounts: [] };
  const result = await createAccount(config, "config.local.json", {}, {
    randomUUID: () => "abcdef12-3456-7890-abcd-ef1234567890",
    makeDirectory: async () => {},
    persistConfig: async () => {}
  });

  assert.equal(result.account.label, "New account");
  assert.equal(result.account.id, "new-account-abcdef12");
  assert.equal(result.account.status, "needs_login");
  assert.deepEqual(result.accounts, [result.account]);
});

test("creating a new login account preserves existing logged-out managed accounts", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: [
      {
        id: "new-account-old",
        label: "New account",
        codexHome: "C:\\CodeRemoteManager\\accounts\\new-account-old\\codex-home"
      },
      {
        id: "preconfigured",
        label: "Preconfigured",
        codexHome: "C:\\External\\codex-home"
      }
    ]
  };
  let persisted;

  await createAccount(config, "config.local.json", {}, {
    randomUUID: () => "abcdef12-3456-7890-abcd-ef1234567890",
    makeDirectory: async () => {},
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; },
    fileExists: async () => false
  });

  assert.deepEqual(persisted.accounts.map((account) => account.id), ["new-account-old", "preconfigured", "new-account-abcdef12"]);
  assert.deepEqual(config.accounts.map((account) => account.id), ["new-account-old", "preconfigured", "new-account-abcdef12"]);
});

test("serializes concurrent account creation without losing either configured ID", async () => {
  const config = { dataDir: "C:\\CodeRemoteManager\\data", accounts: [] };
  let markFirstPersistStarted;
  let releaseFirstPersist;
  const firstPersistStarted = new Promise((resolve) => { markFirstPersistStarted = resolve; });
  const firstPersistReleased = new Promise((resolve) => { releaseFirstPersist = resolve; });

  const first = createAccount(config, "config.local.json", { label: "First" }, {
    randomUUID: () => "aaaaaaaa-1111-2222-3333-444444444444",
    makeDirectory: async () => {},
    persistConfig: async () => {
      markFirstPersistStarted();
      await firstPersistReleased;
    }
  });
  await firstPersistStarted;

  const second = createAccount(config, "config.local.json", { label: "Second" }, {
    randomUUID: () => "bbbbbbbb-1111-2222-3333-444444444444",
    makeDirectory: async () => {},
    persistConfig: async () => {}
  });
  await new Promise((resolve) => setImmediate(resolve));
  releaseFirstPersist();
  await Promise.all([first, second]);

  assert.deepEqual(config.accounts.map((account) => account.id), ["first-aaaaaaaa", "second-bbbbbbbb"]);
});

test("downgrade marks only excess execution accounts locked without deleting accounts or history sources", async () => {
  const homes = await Promise.all([authenticatedHome(), authenticatedHome(), authenticatedHome()]);
  const config = { accounts: [
    { id: "account-a", label: "A", codexHome: homes[0] },
    { id: "account-b", label: "B", codexHome: homes[1] },
    { id: "account-c", label: "C", codexHome: homes[2] },
    { id: "history", label: "History", codexHome: "history-home", historyOnly: true },
  ] };
  try {
    const accounts = await listPublicAccounts(
      config,
      async () => ({ account: { type: "chatgpt", email: "person@example.com" } }),
      (accountId) => ({ allowed: accountId === "account-a", entitlementLocked: accountId !== "account-a" })
    );

    assert.equal(Object.hasOwn(accounts[0], "entitlementLocked"), false);
    assert.equal(accounts[1].entitlementLocked, true);
    assert.equal(accounts[2].entitlementLocked, true);
    assert.deepEqual(config.accounts.map(({ id, historyOnly }) => ({ id, historyOnly })), [
      { id: "account-a", historyOnly: undefined },
      { id: "account-b", historyOnly: undefined },
      { id: "account-c", historyOnly: undefined },
      { id: "history", historyOnly: true },
    ]);
  } finally {
    await Promise.all(homes.map((home) => rm(home, { recursive: true, force: true })));
  }
});

test("direct account creation enforces capacity before filesystem or config writes", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: [{ id: "existing", label: "Existing", codexHome: "existing-home" }],
  };
  let directoryCalls = 0;
  let persistCalls = 0;
  await assert.rejects(createAccount(config, "config.local.json", {}, {
    assertCanAddExecutionAccount: () => assertCanAddExecutionAccount({
      accounts: config.accounts,
      entitlement: { tier: "free", maxAccounts: 1 },
    }),
    makeDirectory: async () => { directoryCalls += 1; },
    persistConfig: async () => { persistCalls += 1; },
  }), (error) => error?.code === "pro_required");

  assert.equal(directoryCalls, 0);
  assert.equal(persistCalls, 0);
  assert.equal(config.accounts.length, 1);
});

test("serialized final account persistence prevents concurrent Pro overflow", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: [
      ...Array.from({ length: 4 }, (_, index) => ({ id: `account-${index}`, label: "Account", codexHome: `home-${index}` })),
      { id: "history", label: "History", codexHome: "history-home", historyOnly: true },
    ],
  };
  let releaseFirst;
  let markFirstStarted;
  const firstStarted = new Promise((resolve) => { markFirstStarted = resolve; });
  const firstReleased = new Promise((resolve) => { releaseFirst = resolve; });
  let persistCalls = 0;
  const dependencies = {
    assertCanAddExecutionAccount: () => assertCanAddExecutionAccount({
      accounts: config.accounts,
      entitlement: { tier: "pro", maxAccounts: 5 },
    }),
    persistConfig: async () => {
      persistCalls += 1;
      if (persistCalls === 1) {
        markFirstStarted();
        await firstReleased;
      }
    },
  };
  const first = persistCreatedAccount(config, "config.local.json", { id: "candidate-a", label: "A", codexHome: "candidate-a" }, dependencies);
  await firstStarted;
  const second = persistCreatedAccount(config, "config.local.json", { id: "candidate-b", label: "B", codexHome: "candidate-b" }, dependencies);
  releaseFirst();

  const results = await Promise.allSettled([first, second]);
  assert.equal(results.filter((result) => result.status === "fulfilled").length, 1);
  const rejected = results.find((result) => result.status === "rejected");
  assert.equal(rejected.reason.code, "account_limit_reached");
  assert.equal(config.accounts.filter((account) => account.historyOnly !== true).length, 5);
  assert.equal(persistCalls, 1);
});

test("account cleanup preserves logged-out managed accounts until explicit removal", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: [
      {
        id: "new-account-old",
        label: "New account",
        codexHome: "C:\\CodeRemoteManager\\accounts\\new-account-old\\codex-home"
      },
      {
        id: "desktop",
        label: "Desktop",
        codexHome: "C:\\Desktop\\codex-home"
      }
    ]
  };
  let persisted;

  const result = await pruneUnauthenticatedManagedAccounts(config, "config.local.json", {
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; },
    fileExists: async () => false
  });

  assert.deepEqual(result, { pruned: false });
  assert.equal(persisted, undefined);
  assert.deepEqual(config.accounts.map((account) => account.id), ["new-account-old", "desktop"]);
});

test("account cleanup skips config writes when there is no stale managed account", async () => {
  const config = {
    dataDir: "C:\\CodeRemoteManager\\data",
    accounts: [{ id: "desktop", label: "Desktop", codexHome: "C:\\Desktop\\codex-home" }]
  };

  const result = await pruneUnauthenticatedManagedAccounts(config, "config.local.json", {
    persistConfig: async () => assert.fail("clean config must not be rewritten"),
    fileExists: async () => false
  });

  assert.deepEqual(result, { pruned: false });
  assert.deepEqual(config.accounts.map((account) => account.id), ["desktop"]);
});

test("rejects invalid account labels", async () => {
  const config = { dataDir: "data", accounts: [{ id: "a", label: "A", codexHome: "a" }] };
  for (const label of ["   ", "x".repeat(81)]) {
    await assert.rejects(
      createAccount(config, "config.local.json", { label }),
      (error) => error.message === "invalid_account_label" && error.status === 400
    );
  }
});

test("does not mutate live config when persistence fails", async () => {
  const config = { dataDir: "data", accounts: [{ id: "a", label: "A", codexHome: "a" }] };
  await assert.rejects(
    createAccount(config, "config.local.json", { label: "B" }, {
      randomUUID: () => "abcdef12-3456-7890-abcd-ef1234567890",
      persistConfig: async () => { throw new Error("disk path leaked"); }
    }),
    (error) => error.message === "account_config_write_failed" && error.status === 500
  );
  assert.deepEqual(config.accounts.map((item) => item.id), ["a"]);
});

test("removes a visible account by converting it to a hidden history source", async () => {
  const codexHomeA = await authenticatedHome();
  const codexHomeB = await authenticatedHome();
  const config = { accounts: [
    { id: "a", label: "A", codexHome: codexHomeA },
    { id: "b", label: "B", codexHome: codexHomeB },
    { id: "desktop", label: "Desktop", codexHome: "desktop", historyOnly: true }
  ] };
  let persisted;
  const detached = [];
  const result = await removeAccount(config, "config.local.json", "b", {
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; },
    listAccounts: async () => [{ id: "b", email: "PERSON@example.com", status: "logged_in" }],
    tokenUsageStore: { detach: async (...args) => detached.push(args) }
  });
  assert.deepEqual(result.accounts.map((item) => item.id), ["a"]);
  assert.deepEqual(persisted.accounts.map(({ id, historyOnly }) => ({ id, historyOnly })), [
    { id: "a", historyOnly: undefined },
    { id: "b", historyOnly: true },
    { id: "desktop", historyOnly: true }
  ]);
  assert.deepEqual(config.accounts, persisted.accounts);
  assert.deepEqual(detached, [["b", "person@example.com"]]);
});

test("updates visible account label and persists safely", async () => {
  const codexHome = await authenticatedHome();
  const config = { accounts: [
    { id: "a", label: "Account A", codexHome },
    { id: "desktop", label: "Desktop", codexHome: "desktop", historyOnly: true }
  ] };
  let persisted;
  const result = await updateAccountLabel(config, "config.local.json", "a", { label: "person@example.com" }, {
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; }
  });

  assert.equal(result.account.label, "person@example.com");
  assert.equal(result.accounts[0].label, "person@example.com");
  assert.equal(persisted.accounts[0].label, "person@example.com");
  assert.equal(config.accounts[0].label, "person@example.com");
  assert.equal(JSON.stringify(result).includes("codexHome"), false);
});

test("rejects invalid, hidden, and unknown account label updates", async () => {
  const config = { accounts: [
    { id: "a", label: "Account A", codexHome: "a" },
    { id: "desktop", label: "Desktop", codexHome: "desktop", historyOnly: true }
  ] };

  await assert.rejects(
    updateAccountLabel(config, "config.local.json", "a", { label: " " }),
    (error) => error.message === "invalid_account_label" && error.status === 400
  );
  for (const accountId of ["missing", "desktop"]) {
    await assert.rejects(
      updateAccountLabel(config, "config.local.json", accountId, { label: "x" }),
      (error) => error.message === "account_not_found" && error.status === 404
    );
  }
});

test("rejects hidden and unknown account removal", async () => {
  const base = [
    { id: "a", label: "A", codexHome: "a" },
    { id: "desktop", label: "Desktop", codexHome: "desktop", historyOnly: true }
  ];
  for (const accountId of ["missing", "desktop"]) {
    await assert.rejects(
      removeAccount({ accounts: structuredClone(base) }, "config.local.json", accountId),
      (error) => error.message === "account_not_found" && error.status === 404
    );
  }
});

test("removes the last visible account by preserving it and existing sources as hidden history", async () => {
  const config = { accounts: [
    { id: "a", label: "A", codexHome: "a" },
    { id: "desktop", label: "Desktop", codexHome: "desktop", historyOnly: true }
  ] };
  let persisted;

  const result = await removeAccount(config, "config.local.json", "a", {
    persistConfig: async (_path, nextConfig) => { persisted = nextConfig; }
  });

  assert.deepEqual(result.accounts, []);
  assert.deepEqual(persisted.accounts.map(({ id, historyOnly }) => ({ id, historyOnly })), [
    { id: "a", historyOnly: true },
    { id: "desktop", historyOnly: true }
  ]);
  assert.deepEqual(config.accounts, persisted.accounts);
});

test("removing the last account preserves it as hidden history in a reloadable config", async () => {
  const directory = await mkdtemp(join(tmpdir(), "code-remote-manager-account-"));
  const configPath = join(directory, "config.local.json");
  const previous = process.env.CODE_REMOTE_MANAGER_CONFIG_PATH;
  const config = {
    codexCliPath: "codex.cmd",
    engine: "fake",
    bindHost: "127.0.0.1",
    port: 43110,
    dataDir: join(directory, "data"),
    accounts: [{ id: "a", label: "A", codexHome: join(directory, "home") }],
    workspaces: [{ id: "project", label: "Project", path: directory }]
  };
  await writeFile(configPath, JSON.stringify(config, null, 2));

  try {
    await removeAccount(config, configPath, "a");
    process.env.CODE_REMOTE_MANAGER_CONFIG_PATH = configPath;
    const reloaded = await loadConfig();
    assert.deepEqual(reloaded.config.accounts, [{
      id: "a",
      label: "A",
      codexHome: join(directory, "home"),
      historyOnly: true
    }]);
  } finally {
    if (previous === undefined) delete process.env.CODE_REMOTE_MANAGER_CONFIG_PATH;
    else process.env.CODE_REMOTE_MANAGER_CONFIG_PATH = previous;
    await rm(directory, { recursive: true, force: true });
  }
});

async function authenticatedHome() {
  const codexHome = await mkdtemp(join(tmpdir(), "code-remote-manager-account-"));
  await writeFile(join(codexHome, "auth.json"), JSON.stringify({
    OPENAI_ACCOUNT_EMAIL: "person@example.com"
  }));
  return codexHome;
}
