import test from "node:test";
import assert from "node:assert/strict";
import { resolveApplicationDataRoute } from "./application-data-routes.js";

test("PC reset requires the installed managed host and an explicit confirmation", async () => {
  const url = new URL("http://localhost/application-data");
  let deleteCalls = 0;
  const context = {
    readJson: async () => ({}),
    managedHost: true,
    deleteData: async () => { deleteCalls += 1; }
  };

  await assert.rejects(resolveApplicationDataRoute({ method: "DELETE" }, url, context), error(400, "application_data_confirmation_required"));
  assert.equal(deleteCalls, 0);

  await assert.rejects(resolveApplicationDataRoute({ method: "DELETE" }, url, {
    ...context,
    managedHost: false,
    readJson: async () => ({ confirmation: "delete_code_remote_manager_data" })
  }), error(409, "application_data_restart_unavailable"));
  assert.equal(deleteCalls, 0);
});

test("PC reset refuses running or queued work before deleting anything", async () => {
  let deleteCalls = 0;
  await assert.rejects(resolveApplicationDataRoute({ method: "DELETE" }, new URL("http://localhost/application-data"), {
    managedHost: true,
    readJson: async () => ({ confirmation: "delete_code_remote_manager_data" }),
    prepareSessions: async () => { throw Object.assign(new Error("application_data_in_use"), { status: 409 }); },
    deleteData: async () => { deleteCalls += 1; }
  }), error(409, "application_data_in_use"));
  assert.equal(deleteCalls, 0);
});

test("confirmed PC reset clears runtime data, expires pairing, then requests a restart", async () => {
  const calls = [];
  const result = await resolveApplicationDataRoute({ method: "DELETE" }, new URL("http://localhost/application-data"), {
    managedHost: true,
    readJson: async () => ({ confirmation: "delete_code_remote_manager_data" }),
    prepareSessions: async () => { calls.push("prepare"); },
    stopRuntime: () => { calls.push("stop-runtime"); },
    deleteData: async () => { calls.push("delete"); return { deleted: true, pendingCleanup: 0 }; },
    expirePairing: () => { calls.push("expire-pairing"); },
    requestRestart: () => { calls.push("restart"); }
  });

  assert.deepEqual(calls, ["prepare", "stop-runtime", "delete", "expire-pairing", "restart"]);
  assert.deepEqual(result, { status: 202, body: { reset: { scheduled: true, pendingCleanup: 0 } } });
});

function error(status, message) {
  return (value) => value?.status === status && value?.message === message;
}
