import { describe, expect, test } from "bun:test";
import { verifyAsync } from "@noble/ed25519";
import { base64UrlToBytes, textToBytes } from "../src/encoding";
import { GeoApiClient } from "../src/GeoApiClient";
import { signMessage } from "../src/keys";

class MemoryStorage {
  private data = new Map<string, string>();

  getItem(key: string): string | null {
    return this.data.get(key) ?? null;
  }

  setItem(key: string, value: string): void {
    this.data.set(key, value);
  }

  removeItem(key: string): void {
    this.data.delete(key);
  }
}

describe("GeoApiClient keys", () => {
  test("ensureKeysInStorage creates and persists keypair", async () => {
    const storage = new MemoryStorage();
    const client = new GeoApiClient("http://localhost:8080", storage);

    const keysA = await client.ensureKeysInStorage();
    const keysB = await client.ensureKeysInStorage();

    expect(keysA.publicKey.length).toBeGreaterThan(10);
    expect(keysA.privateKey.length).toBeGreaterThan(10);
    expect(keysA.publicKey).toEqual(keysB.publicKey);
    expect(keysA.privateKey).toEqual(keysB.privateKey);
  });

  test("signMessage creates verifiable signature", async () => {
    const storage = new MemoryStorage();
    const client = new GeoApiClient("http://localhost:8080", storage);
    const keys = await client.ensureKeysInStorage();
    const message = "login:testnonce";
    const sigB64 = await signMessage(keys.privateKey, message);

    const ok = await verifyAsync(base64UrlToBytes(sigB64), textToBytes(message), base64UrlToBytes(keys.publicKey));
    expect(ok).toBe(true);
  });
});
