import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
import { dirname } from 'node:path';

// Maps an OpenClaw agentId to its Fabric machine credential (Center API key).
// One key per agent; minted via Center CLI: `node dist/cli.js user apikey`.
export type IdentityEntry = {
  agentId: string;
  fabricApiKey: string;
  // cached after first agent/login (for logging / display only)
  fabricUserId?: string;
  displayName?: string;
};

type IdentityFile = { entries: IdentityEntry[] };

export class IdentityRegistry {
  private entries = new Map<string, IdentityEntry>();

  constructor(private readonly filePath: string) {
    this.load();
  }

  private load(): void {
    if (!existsSync(this.filePath)) return;
    try {
      const data = JSON.parse(readFileSync(this.filePath, 'utf8')) as IdentityFile;
      for (const e of data.entries ?? []) {
        if (e.agentId && e.fabricApiKey) this.entries.set(e.agentId, e);
      }
    } catch {
      // corrupt file -> start empty; upsert will rewrite
    }
  }

  private persist(): void {
    mkdirSync(dirname(this.filePath), { recursive: true });
    const data: IdentityFile = { entries: [...this.entries.values()] };
    writeFileSync(this.filePath, JSON.stringify(data, null, 2));
  }

  list(): IdentityEntry[] {
    return [...this.entries.values()];
  }

  findByAgentId(agentId: string): IdentityEntry | undefined {
    return this.entries.get(agentId);
  }

  upsert(entry: IdentityEntry): void {
    const prev = this.entries.get(entry.agentId);
    this.entries.set(entry.agentId, { ...prev, ...entry });
    this.persist();
  }
}
