import { test, expect } from '../fixtures';

/**
 * Log Ingestion Tests
 * Covers: HTTP API ingestion, batch processing, PII detection
 * Target: 100% coverage on critical paths
 */

test.describe('Log Ingestion @ingest @critical', () => {
  
  test('should ingest single log via HTTP API', async ({ apiClient, testData }) => {
    // Create a scenario first
    const scenario = await testData.createScenario({
      name: 'Ingest Test',
      region: 'us-east-1',
      tags: [],
    });
    
    // Ingest a log
    const response = await apiClient.ingestLog(scenario.id, {
      message: 'Test log message',
      source: 'e2e-test',
      level: 'INFO',
    });
    
    expect(response.status()).toBe(200);
  });

  test('should ingest batch of logs', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Batch Ingest Test',
      region: 'us-east-1',
      tags: [],
    });
    
    // Ingest multiple logs
    const logs = Array.from({ length: 10 }, (_, i) => ({
      message: `Batch log ${i}`,
      source: 'batch-test',
      level: 'INFO',
    }));
    
    for (const log of logs) {
      const response = await apiClient.ingestLog(scenario.id, log);
      expect(response.status()).toBe(200);
    }
  });

  test('should detect email PII in logs', async ({ authenticatedPage, testData }) => {
    const scenario = await testData.createScenario({
      name: 'PII Detection Test',
      region: 'us-east-1',
      tags: [],
    });
    
    // Add log with PII
    await testData.addScenarioLogWithPII(scenario.id);
    
    // Navigate to scenario and check PII detection
    await authenticatedPage.goto(`/scenarios/${scenario.id}`);
    await authenticatedPage.click('[data-testid="pii-tab"]');
    
    await expect(authenticatedPage.locator('[data-testid="pii-alert-count"]')).toContainText('1');
    await expect(authenticatedPage.locator('[data-testid="pii-type-email"]')).toBeVisible();
  });

  test('should require X-Scenario-ID header', async ({ apiClient }) => {
    const response = await apiClient.context!.post('/ingest', {
      data: {
        message: 'Test without scenario ID',
        source: 'test',
      },
    });
    
    expect(response.status()).toBe(400);
  });

  test('should reject invalid scenario ID', async ({ apiClient }) => {
    const response = await apiClient.ingestLog('invalid-uuid', {
      message: 'Test with invalid ID',
      source: 'test',
    });
    
    expect(response.status()).toBe(404);
  });

  test('should handle large log messages', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Large Log Test',
      region: 'us-east-1',
      tags: [],
    });
    
    const largeMessage = 'A'.repeat(10000);
    
    const response = await apiClient.ingestLog(scenario.id, {
      message: largeMessage,
      source: 'large-test',
    });
    
    expect(response.status()).toBe(200);
  });

  test('should deduplicate identical logs', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Deduplication Test',
      region: 'us-east-1',
      tags: [],
    });
    
    // Send same log twice
    const log = {
      message: 'Duplicate log message',
      source: 'dedup-test',
      level: 'INFO',
    };
    
    await apiClient.ingestLog(scenario.id, log);
    await apiClient.ingestLog(scenario.id, log);
    
    // Navigate to logs tab
    await testData.apiContext!.get(`/api/v1/scenarios/${scenario.id}/logs`, {
      headers: { Authorization: `Bearer ${testData.authToken}` },
    });
    
    // Check deduplication
    // This would depend on your specific implementation
  });

  test('should ingest logs with metadata', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Metadata Test',
      region: 'us-east-1',
      tags: [],
    });
    
    const response = await apiClient.ingestLog(scenario.id, {
      message: 'Log with metadata',
      source: 'metadata-test',
      level: 'INFO',
      metadata: {
        requestId: 'req-123',
        userId: 'user-456',
        traceId: 'trace-789',
      },
    });
    
    expect(response.status()).toBe(200);
  });

  test('should handle different log levels', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Log Levels Test',
      region: 'us-east-1',
      tags: [],
    });
    
    const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'];
    
    for (const level of levels) {
      const response = await apiClient.ingestLog(scenario.id, {
        message: `${level} level test`,
        source: 'levels-test',
        level,
      });
      
      expect(response.status()).toBe(200);
    }
  });

  test('should apply rate limiting on ingest endpoint', async ({ apiClient, testData }) => {
    const scenario = await testData.createScenario({
      name: 'Rate Limit Test',
      region: 'us-east-1',
      tags: [],
    });
    
    // Send many rapid requests
    const responses = [];
    for (let i = 0; i < 1100; i++) {
      const response = await apiClient.ingestLog(scenario.id, {
        message: `Rate limit test ${i}`,
        source: 'rate-limit-test',
      });
      responses.push(response.status());
      
      if (response.status() === 429) {
        break;
      }
    }
    
    // Should eventually hit rate limit
    expect(responses).toContain(429);
  });
});

test.describe('Ingest via Logstash @ingest @integration', () => {
  
  test('should accept Logstash-compatible format', async () => {
    // Test Logstash HTTP output compatibility
    const logstashFormat = {
      '@timestamp': new Date().toISOString(),
      message: 'Logstash format test',
      host: 'test-host',
      type: 'application',
    };
    
    // This would test the actual Logstash integration
    // Implementation depends on your setup
  });

  test('should handle Logstash batch format', async () => {
    // Test batch ingestion from Logstash
    const batch = [
      { message: 'Log 1', '@timestamp': new Date().toISOString() },
      { message: 'Log 2', '@timestamp': new Date().toISOString() },
      { message: 'Log 3', '@timestamp': new Date().toISOString() },
    ];
    
    // Implementation depends on your setup
  });
});
