/**
 * Shield Health Check Tests (S5)
 * Verifies Shield health integration in /health and /ready endpoints
 */

import { describe, it, expect, beforeEach } from '@jest/globals';
import { Shield } from '@4runr/shield';
import { checkShield } from '../health/index.js';

function resetShieldSingleton(): void {
  (Shield as unknown as { instance?: Shield }).instance = undefined;
}

describe('Shield Health Check (S5)', () => {
  beforeEach(() => {
    resetShieldSingleton();
    delete process.env['OPENAI_API_KEY'];
  });

  describe('checkShield', () => {
    it('should return operational status when Shield configured correctly', async () => {
      const shield = Shield.getInstance();
      shield.updateConfig({
        enabled: true,
        mode: 'enforce',
        hallucination: { enabled: true, action: 'flag' }, // No rewrite, no OPENAI_API_KEY needed
      });

      const health = await checkShield();

      expect(health.enabled).toBe(true);
      expect(health.mode).toBe('enforce');
      expect(health.detectors).toHaveProperty('pii');
      expect(health.detectors).toHaveProperty('injection');
      expect(health.detectors).toHaveProperty('hallucination');
      expect(health.status).toBe('operational');
      expect(health.warnings).toBeUndefined();
    });

    it('should return misconfigured when enabled=true but mode=off', async () => {
      const shield = Shield.getInstance();
      shield.updateConfig({ enabled: true, mode: 'off' });

      const health = await checkShield();

      expect(health.enabled).toBe(false); // isEnabled() returns false when mode=off
      expect(health.mode).toBe('off');
      expect(health.status).toBe('misconfigured');
      expect(health.warnings).toContain('Shield enabled flag true but mode is off');
    });

    it('should warn when rewrite enabled without OPENAI_API_KEY', async () => {
      const shield = Shield.getInstance();
      shield.updateConfig({
        enabled: true,
        mode: 'enforce',
        hallucination: { enabled: true, action: 'rewrite' },
        rewrite: { enabled: true },
      });

      const health = await checkShield();

      expect(health.status).toBe('misconfigured');
      expect(health.warnings).toContain('Hallucination rewrite enabled but OPENAI_API_KEY not set');
    });

    it('should not warn when rewrite enabled with OPENAI_API_KEY', async () => {
      process.env['OPENAI_API_KEY'] = 'sk-test-key';

      const shield = Shield.getInstance();
      shield.updateConfig({
        enabled: true,
        mode: 'enforce',
        hallucination: { enabled: true, action: 'rewrite' },
        rewrite: { enabled: true },
      });

      const health = await checkShield();

      expect(health.status).toBe('operational');
      expect(health.warnings).toBeUndefined();
    });

    it('should return operational in monitor mode', async () => {
      const shield = Shield.getInstance();
      shield.updateConfig({ enabled: true, mode: 'monitor' });

      const health = await checkShield();

      expect(health.enabled).toBe(true);
      expect(health.mode).toBe('monitor');
      expect(health.status).toBe('operational');
    });

    it('should report all detector statuses', async () => {
      const shield = Shield.getInstance();
      shield.updateConfig({
        enabled: true,
        mode: 'enforce',
        pii: { enabled: true, maskFormat: '[REDACTED]' },
        injection: { enabled: true, action: 'block' },
        hallucination: { enabled: false },
      });

      const health = await checkShield();

      expect(health.detectors.pii).toBe(true);
      expect(health.detectors.injection).toBe(true);
      expect(health.detectors.hallucination).toBe(false);
    });

    it('should handle Shield getInstance errors gracefully', async () => {
      // Force Shield to throw (simulate broken singleton)
      const originalGetInstance = Shield.getInstance;
      Shield.getInstance = (() => {
        throw new Error('Shield initialization failed');
      }) as any;

      const health = await checkShield();

      expect(health.enabled).toBe(false);
      expect(health.mode).toBe('unknown');
      expect(health.status).toBe('misconfigured');
      expect(health.warnings).toContain('Shield health check threw error');

      // Restore
      Shield.getInstance = originalGetInstance;
    });
  });

  describe('Health Check Integration', () => {
    it('should include Shield in health check response format', async () => {
      const health = await checkShield();

      // Verify structure matches HealthCheckResult.checks.shield
      expect(health).toHaveProperty('enabled');
      expect(health).toHaveProperty('mode');
      expect(health).toHaveProperty('detectors');
      expect(health).toHaveProperty('status');
      expect(typeof health.enabled).toBe('boolean');
      expect(typeof health.mode).toBe('string');
      expect(typeof health.status).toBe('string');
      expect(['operational', 'misconfigured']).toContain(health.status);
    });
  });
});
