import { SecurityLogger } from '../SecurityLogger';
import { ValidationLogEntry } from '../types';

describe('SecurityLogger', () => {
  let logger: SecurityLogger;

  beforeEach(() => {
    logger = new SecurityLogger();
  });

  describe('logValidationEvent', () => {
    it('should log validation success event', async () => {
      const entry: ValidationLogEntry = {
        timestamp: new Date(),
        fileSize: 1024,
        declaredMime: 'image/png',
        detectedMime: 'image/png',
        validationResult: 'success',
        module: 'record-management',
        endpoint: '/record-attachments',
      };

      await logger.logValidationEvent(entry);
      const logs = logger.getAllLogs();

      expect(logs).toHaveLength(1);
      expect(logs[0].validationResult).toBe('success');
      expect(logs[0].declaredMime).toBe('image/png');
    });

    it('should log validation mismatch event', async () => {
      const entry: ValidationLogEntry = {
        timestamp: new Date(),
        fileSize: 1024,
        declaredMime: 'image/jpeg',
        detectedMime: 'image/png',
        validationResult: 'mismatch',
        errorDetails: 'MIME type mismatch',
        module: 'user-management',
        endpoint: '/theme/upload',
      };

      await logger.logValidationEvent(entry);
      const logs = logger.getAllLogs();

      expect(logs).toHaveLength(1);
      expect(logs[0].validationResult).toBe('mismatch');
      expect(logs[0].errorDetails).toBe('MIME type mismatch');
    });

    it('should log validation error event', async () => {
      const entry: ValidationLogEntry = {
        timestamp: new Date(),
        fileSize: 0,
        declaredMime: 'image/png',
        validationResult: 'error',
        errorDetails: 'File buffer is empty',
        module: 'external-portal',
        endpoint: '/user-documents',
      };

      await logger.logValidationEvent(entry);
      const logs = logger.getAllLogs();

      expect(logs).toHaveLength(1);
      expect(logs[0].validationResult).toBe('error');
    });

    it('should set timestamp if not provided', async () => {
      const entry: ValidationLogEntry = {
        fileSize: 1024,
        declaredMime: 'image/png',
        detectedMime: 'image/png',
        validationResult: 'success',
        module: 'record-management',
        endpoint: '/record-attachments',
      } as any;

      await logger.logValidationEvent(entry);
      const logs = logger.getAllLogs();

      expect(logs[0].timestamp).toBeDefined();
      expect(logs[0].timestamp instanceof Date).toBe(true);
    });
  });

  describe('queryValidationLogs', () => {
    beforeEach(async () => {
      const now = new Date();
      const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);

      await logger.logValidationEvent({
        timestamp: now,
        userId: 'user1',
        fileSize: 1024,
        declaredMime: 'image/png',
        detectedMime: 'image/png',
        validationResult: 'success',
        module: 'record-management',
        endpoint: '/record-attachments',
      });

      await logger.logValidationEvent({
        timestamp: now,
        userId: 'user2',
        fileSize: 2048,
        declaredMime: 'image/jpeg',
        detectedMime: 'image/png',
        validationResult: 'mismatch',
        errorDetails: 'MIME mismatch',
        module: 'user-management',
        endpoint: '/theme/upload',
      });

      await logger.logValidationEvent({
        timestamp: yesterday,
        userId: 'user1',
        fileSize: 512,
        declaredMime: 'application/pdf',
        validationResult: 'error',
        errorDetails: 'File buffer is empty',
        module: 'external-portal',
        endpoint: '/user-documents',
      });
    });

    it('should query logs by module', async () => {
      const logs = await logger.queryValidationLogs({
        module: 'record-management',
      });
      expect(logs).toHaveLength(1);
      expect(logs[0].module).toBe('record-management');
    });

    it('should query logs by validation result', async () => {
      const logs = await logger.queryValidationLogs({
        validationResult: 'mismatch',
      });
      expect(logs).toHaveLength(1);
      expect(logs[0].validationResult).toBe('mismatch');
    });

    it('should query logs by user ID', async () => {
      const logs = await logger.queryValidationLogs({ userId: 'user1' });
      expect(logs).toHaveLength(2);
      expect(logs.every((log) => log.userId === 'user1')).toBe(true);
    });

    it('should query logs by date range', async () => {
      const now = new Date();
      const today = new Date(now.getTime() - 12 * 60 * 60 * 1000);

      const logs = await logger.queryValidationLogs({
        startDate: today,
        endDate: now,
      });
      expect(logs).toHaveLength(2);
    });

    it('should return all logs with no filters', async () => {
      const logs = await logger.queryValidationLogs({});
      expect(logs).toHaveLength(3);
    });
  });

  describe('clearLogs', () => {
    it('should clear all logs', async () => {
      await logger.logValidationEvent({
        timestamp: new Date(),
        fileSize: 1024,
        declaredMime: 'image/png',
        detectedMime: 'image/png',
        validationResult: 'success',
        module: 'record-management',
        endpoint: '/record-attachments',
      });

      expect(logger.getAllLogs()).toHaveLength(1);

      logger.clearLogs();

      expect(logger.getAllLogs()).toHaveLength(0);
    });
  });
});
