import { assert, assertEquals } from '@std/assert';

import { SecretSettingsManager } from '../ts/database/secret-settings.ts';

class FakeAuthRepository {
  public settings = new Map<string, string>();
  public secretSettings = new Map<string, string>();

  getSetting(key: string): string | null {
    return this.settings.get(key) ?? null;
  }

  setSetting(key: string, value: string): void {
    this.settings.set(key, value);
  }

  deleteSetting(key: string): void {
    this.settings.delete(key);
  }

  getSecretSetting(key: string): string | null {
    return this.secretSettings.get(key) ?? null;
  }

  setSecretSetting(key: string, value: string): void {
    this.secretSettings.set(key, value);
  }

  deleteSecretSetting(key: string): void {
    this.secretSettings.delete(key);
  }
}

Deno.test('secret settings migrate legacy plaintext aliases into encrypted storage', async () => {
  const authRepo = new FakeAuthRepository();
  authRepo.setSetting('cloudflareAPIKey', 'cf-secret-token');

  const secretSettings = new SecretSettingsManager(authRepo as any);
  const token = await secretSettings.get('cloudflareToken');

  assertEquals(token, 'cf-secret-token');
  assertEquals(authRepo.getSetting('cloudflareAPIKey'), null);
  assertEquals(authRepo.getSetting('cloudflareToken'), null);

  const storedSecret = authRepo.getSecretSetting('cloudflareToken');
  assert(storedSecret?.startsWith('enc:v1:'));
});

Deno.test('secret settings canonicalize aliases and clear old secret entries', async () => {
  const authRepo = new FakeAuthRepository();
  const secretSettings = new SecretSettingsManager(authRepo as any);

  await secretSettings.set('backup_encryption_password', 'backup-passphrase');

  assertEquals(await secretSettings.get('backupPassword'), 'backup-passphrase');
  assert(authRepo.getSecretSetting('backupPassword')?.startsWith('enc:v1:'));
  assertEquals(authRepo.getSecretSetting('backup_encryption_password'), null);

  secretSettings.clear('backupPassword');
  assertEquals(await secretSettings.get('backupPassword'), null);
});

Deno.test('secret settings treat dcrouter gateway token as encrypted secret', async () => {
  const authRepo = new FakeAuthRepository();
  authRepo.setSetting('externalGatewayApiToken', 'dcr-secret-token');

  const secretSettings = new SecretSettingsManager(authRepo as any);
  const token = await secretSettings.get('dcrouterGatewayApiToken');

  assertEquals(token, 'dcr-secret-token');
  assertEquals(authRepo.getSetting('externalGatewayApiToken'), null);
  assert(authRepo.getSecretSetting('dcrouterGatewayApiToken')?.startsWith('enc:v1:'));
});
