import test from "node:test";
import assert from "node:assert/strict";
import { resolveUsageRoute } from "./usage-routes.js";

const config = { accounts: [{ id: "a", codexHome: "private" }] };
const request = (method) => ({ method });

test("usage reads record a safe history sample", async () => {
  const recorded = [];
  const usage = { primary: { remainingPercent: 70 }, secondary: null, resetCreditsAvailable: 1 };
  const result = await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage"), {
    config,
    readUsage: async () => usage,
    historyStore: { record: async (...args) => recorded.push(args) }
  });

  assert.deepEqual(result, { status: 200, body: usage });
  assert.deepEqual(recorded, [["a", usage]]);
});

test("token usage reads return the selected account daily totals", async () => {
  const tokenUsage = { dailyUsageBuckets: [{ startDate: "2026-07-14", tokens: 1200 }], summary: { lifetimeTokens: 1200 } };
  const recorded = [];
  const result = await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/tokens"), {
    config,
    readTokenUsage: async (_config, accountId) => {
      assert.equal(accountId, "a");
      return tokenUsage;
    },
    tokenUsageStore: {
      async record(...args) {
        recorded.push(args);
        return { ...args[1], cached: true };
      }
    }
  });

  assert.deepEqual(result, { status: 200, body: { ...tokenUsage, cached: true } });
  assert.deepEqual(recorded, [["a", tokenUsage]]);
});

test("token usage reads fall back to the last graph snapshot when live usage is unavailable", async () => {
  const cached = { dailyUsageBuckets: [{ startDate: "2026-07-14", tokens: 1200 }], summary: { lifetimeTokens: 1200 } };
  const result = await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/tokens"), {
    config,
    readTokenUsage: async () => { throw new Error("account_login_required"); },
    tokenUsageStore: { read: async (accountId) => accountId === "a" ? cached : null }
  });

  assert.deepEqual(result, { status: 200, body: cached });
});

test("usage history defaults to 1 day and supports bounded 1, 3, 7, and 30 day ranges", async () => {
  const calls = [];
  const context = {
    config,
    now: () => new Date("2026-07-14T00:00:00.000Z"),
    historyStore: { history: async (...args) => { calls.push(args); return [{ at: "safe" }]; } }
  };
  const defaultResult = await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/history"), context);
  const result = await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/history?days=30"), context);

  assert.deepEqual(defaultResult, { status: 200, body: { points: [{ at: "safe" }] } });
  assert.deepEqual(result, { status: 200, body: { points: [{ at: "safe" }] } });
  assert.equal(calls[0][0], "a");
  assert.equal(calls[0][1].toISOString(), "2026-07-13T00:00:00.000Z");
  assert.equal(calls[1][1].toISOString(), "2026-06-14T00:00:00.000Z");

  await resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/history?days=1"), context);
  assert.equal(calls[2][1].toISOString(), "2026-07-13T00:00:00.000Z");

  await assert.rejects(
    resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/a/usage/history?days=365"), { config, historyStore: {} }),
    /invalid_usage_history_range/
  );
});

test("usage routes reject unknown accounts and ignore unrelated paths", async () => {
  await assert.rejects(
    resolveUsageRoute(request("GET"), new URL("http://localhost/accounts/missing/usage/history"), { config, historyStore: {} }),
    /account_not_found/
  );
  assert.equal(await resolveUsageRoute(request("GET"), new URL("http://localhost/threads"), { config }), null);
});
