/**
 * Tests for the audit-logger security fixes [DC-028]:
 *   - /auth/gate and /auth/app-token must NOT be skipped (they expose creds)
 *   - Other GETs remain skipped (probes, dashboards)
 *   - The new credential-injection / app-token-issue actions resolve
 *
 * These tests focus on shouldSkip() and resolveAction() in isolation.
 * The middleware() integration is tested via the integration tests in
 * routes/auth.*.test.js.
 */

const AuditLogger = require('../src/security/audit-logger');

// Build a fresh AuditLogger class for testability — the singleton at the
// bottom of the module makes testing awkward otherwise.
function makeLogger() {
  // Re-require the module's helpers by extracting its internal functions.
  // Easier: create an instance and exercise its public methods.
  const logger = Object.create(AuditLogger);
  return logger;
}

describe('AuditLogger [DC-028] shouldSkip', () => {
  // Resolve via instance
  const logger = makeLogger();

  test('skips normal GETs (probes, dashboards)', () => {
    expect(logger.shouldSkip('GET', '/api/v1/services')).toBe(true);
    expect(logger.shouldSkip('GET', '/api/v1/config')).toBe(true);
    expect(logger.shouldSkip('GET', '/api/v1/monitoring/stats')).toBe(true);
    expect(logger.shouldSkip('GET', '/health')).toBe(true);
    expect(logger.shouldSkip('GET', '/api/v1/health')).toBe(true);
  });

  test('skips /totp/verify and /totp/check-session (noisy)', () => {
    expect(logger.shouldSkip('GET', '/api/v1/totp/verify')).toBe(true);
    expect(logger.shouldSkip('GET', '/api/v1/totp/check-session')).toBe(true);
    expect(logger.shouldSkip('POST', '/api/v1/totp/verify')).toBe(true);
  });

  test('does NOT skip /auth/gate (security: credentials exposed)', () => {
    expect(logger.shouldSkip('GET', '/api/v1/auth/gate/plex')).toBe(false);
    expect(logger.shouldSkip('GET', '/api/v1/auth/gate/jellyfin')).toBe(false);
    expect(logger.shouldSkip('GET', '/api/v1/auth/gate/sonarr')).toBe(false);
  });

  test('does NOT skip /auth/app-token (security: tokens issued)', () => {
    expect(logger.shouldSkip('GET', '/api/v1/auth/app-token/plex')).toBe(false);
    expect(logger.shouldSkip('GET', '/api/v1/auth/app-token/jellyfin')).toBe(false);
  });

  test('does NOT skip POST/PUT/DELETE on other routes (normal)', () => {
    expect(logger.shouldSkip('POST', '/api/v1/services')).toBe(false);
    expect(logger.shouldSkip('PUT', '/api/v1/services/abc')).toBe(false);
    expect(logger.shouldSkip('DELETE', '/api/v1/auth/keys/xyz')).toBe(false);
  });
});

describe('AuditLogger [DC-028] resolveAction', () => {
  const logger = makeLogger();

  test('credential-injection resolves for /auth/gate', () => {
    expect(logger.resolveAction('GET', '/api/v1/auth/gate/plex')).toBe('auth.credential-injection');
    expect(logger.resolveAction('GET', '/api/v1/auth/gate/jellyfin')).toBe('auth.credential-injection');
  });

  test('app-token-issue resolves for /auth/app-token', () => {
    expect(logger.resolveAction('GET', '/api/v1/auth/app-token/plex')).toBe('auth.app-token-issue');
    expect(logger.resolveAction('GET', '/api/v1/auth/app-token/jellyfin')).toBe('auth.app-token-issue');
  });

  test('api-key-generate / revoke / jwt-mint resolve', () => {
    expect(logger.resolveAction('POST', '/api/v1/auth/keys')).toBe('auth.api-key-generate');
    expect(logger.resolveAction('DELETE', '/api/v1/auth/keys/abc-123')).toBe('auth.api-key-revoke');
    expect(logger.resolveAction('POST', '/api/v1/auth/jwt')).toBe('auth.jwt-mint');
  });

  test('existing actions still resolve', () => {
    expect(logger.resolveAction('POST', '/api/v1/site')).toBe('caddy.add-site');
    expect(logger.resolveAction('POST', '/api/v1/totp/setup')).toBe('auth.totp-setup');
  });
});