import test from "node:test";
import assert from "node:assert/strict";
import { clearThisDeviceData, resetThisDeviceData } from "./device-data-reset.js";

test("this-device reset removes only Code Remote Manager storage and caches", async () => {
  const localStorage = memoryStorage({
    "codexRemote.currentSession": "session",
    "codexRemote.theme": "dark",
    "code-remote-manager.composer-chat.one": "draft",
    "another-app.preference": "keep"
  });
  const sessionStorage = memoryStorage({
    "codexRemote.changePc": "1",
    "another-app.temporary": "keep"
  });
  const deletedCaches = [];
  const cacheStorage = {
    keys: async () => ["code-remote-manager-shell-v2", "another-app-cache"],
    delete: async (key) => { deletedCaches.push(key); return true; }
  };

  await clearThisDeviceData({ localStorage, sessionStorage, cacheStorage });

  assert.deepEqual(localStorage.values(), { "another-app.preference": "keep" });
  assert.deepEqual(sessionStorage.values(), { "another-app.temporary": "keep" });
  assert.deepEqual(deletedCaches, ["code-remote-manager-shell-v2"]);
});

test("this-device reset revokes the current PC pairing before local cleanup", async () => {
  const calls = [];
  const localStorage = memoryStorage({ "codexRemote.serverOrigin": "https://pc.example" });

  await resetThisDeviceData({
    loadSession: async () => { calls.push("load"); return { device: { id: "device-1" } }; },
    revokeDevice: async (deviceId) => { calls.push(`revoke:${deviceId}`); },
    localStorage,
    sessionStorage: memoryStorage(),
    cacheStorage: { keys: async () => [], delete: async () => true }
  });

  assert.deepEqual(calls, ["load", "revoke:device-1"]);
  assert.equal(localStorage.getItem("codexRemote.serverOrigin"), null);
});

test("a failed PC pairing revocation preserves local data for a safe retry", async () => {
  const localStorage = memoryStorage({ "codexRemote.currentSession": "keep-until-retry" });

  await assert.rejects(
    resetThisDeviceData({
      loadSession: async () => ({ device: { id: "device-1" } }),
      revokeDevice: async () => { throw new Error("offline"); },
      localStorage,
      sessionStorage: memoryStorage(),
      cacheStorage: { keys: async () => [], delete: async () => true }
    }),
    /device_reset_failed/
  );

  assert.equal(localStorage.getItem("codexRemote.currentSession"), "keep-until-retry");
});

function memoryStorage(initial = {}) {
  const entries = new Map(Object.entries(initial));
  return {
    get length() { return entries.size; },
    key: (index) => [...entries.keys()][index] ?? null,
    getItem: (key) => entries.get(key) ?? null,
    setItem: (key, value) => entries.set(key, String(value)),
    removeItem: (key) => entries.delete(key),
    values: () => Object.fromEntries(entries)
  };
}
