import http from 'k6/http';
import { check, group } from 'k6';
import { Trend, Counter } from 'k6/metrics';
import { randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

// Custom metrics for benchmark tracking
const apiBenchmarks = {
  health: new Trend('benchmark_health_ms'),
  auth: new Trend('benchmark_auth_ms'),
  scenariosList: new Trend('benchmark_scenarios_list_ms'),
  scenariosCreate: new Trend('benchmark_scenarios_create_ms'),
  metrics: new Trend('benchmark_metrics_ms'),
  ingest: new Trend('benchmark_ingest_ms'),
  reports: new Trend('benchmark_reports_ms'),
};

const throughputCounter = new Counter('requests_total');
const memoryUsage = new Trend('memory_usage_mb');

// Benchmark configuration - run consistent load for baseline measurements
export const options = {
  scenarios: {
    // Baseline benchmark - consistent 100 users for 10 minutes
    baseline: {
      executor: 'constant-vus',
      vus: 100,
      duration: '10m',
      tags: { test_type: 'benchmark_baseline' },
    },
  },
  thresholds: {
    // Baseline performance targets
    'benchmark_health_ms': ['p(50)<50', 'p(95)<100'],
    'benchmark_auth_ms': ['p(50)<200', 'p(95)<400'],
    'benchmark_scenarios_list_ms': ['p(50)<150', 'p(95)<300'],
    'benchmark_ingest_ms': ['p(50)<50', 'p(95)<100'],
  },
  summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(50)', 'p(95)', 'p(99)'],
};

const BASE_URL = __ENV.BASE_URL || 'http://localhost:8000';
const API_V1 = `${BASE_URL}/api/v1`;

export function setup() {
  console.log('Starting benchmark test...');
  console.log('Collecting baseline performance metrics...');
  
  // Warm up the system
  console.log('Warming up system (30 seconds)...');
  for (let i = 0; i < 10; i++) {
    http.get(`${BASE_URL}/health`);
  }
  
  return { 
    startTime: Date.now(),
    testId: `benchmark_${Date.now()}`,
  };
}

export default function(data) {
  const params = {
    headers: {
      'Content-Type': 'application/json',
    },
  };
  
  group('Benchmark - Health Endpoint', () => {
    const start = Date.now();
    const res = http.get(`${BASE_URL}/health`);
    const duration = Date.now() - start;
    
    apiBenchmarks.health.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'health responds successfully': (r) => r.status === 200,
      'health response time acceptable': (r) => r.timings.duration < 200,
    });
  });
  
  group('Benchmark - Authentication', () => {
    const start = Date.now();
    const res = http.post(`${API_V1}/auth/login`, JSON.stringify({
      username: 'benchmark@test.com',
      password: 'benchmark123',
    }), params);
    const duration = Date.now() - start;
    
    apiBenchmarks.auth.add(duration);
    throughputCounter.add(1);
    
    // 401 is expected for invalid credentials, but we measure response time
    check(res, {
      'auth endpoint responds': (r) => r.status !== 0,
    });
  });
  
  group('Benchmark - Scenarios List', () => {
    const start = Date.now();
    const res = http.get(`${API_V1}/scenarios?page=1&page_size=20`, params);
    const duration = Date.now() - start;
    
    apiBenchmarks.scenariosList.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'scenarios list responds': (r) => r.status === 200 || r.status === 401,
      'scenarios list response time acceptable': (r) => r.timings.duration < 500,
    });
  });
  
  group('Benchmark - Scenarios Create', () => {
    const start = Date.now();
    const res = http.post(`${API_V1}/scenarios`, JSON.stringify({
      name: `Benchmark_${randomIntBetween(1, 100000)}`,
      description: 'Benchmark test scenario',
      region: 'us-east-1',
    }), params);
    const duration = Date.now() - start;
    
    apiBenchmarks.scenariosCreate.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'scenarios create responds': (r) => r.status !== 0,
    });
  });
  
  group('Benchmark - Metrics', () => {
    const start = Date.now();
    const res = http.get(`${API_V1}/metrics/dashboard`, params);
    const duration = Date.now() - start;
    
    apiBenchmarks.metrics.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'metrics responds': (r) => r.status === 200 || r.status === 401,
    });
  });
  
  group('Benchmark - Ingest', () => {
    const start = Date.now();
    const res = http.post(`${BASE_URL}/ingest`, JSON.stringify({
      message: `Benchmark log entry ${randomIntBetween(1, 1000000)}`,
      source: 'benchmark',
      level: 'INFO',
    }), {
      ...params,
      headers: {
        ...params.headers,
        'X-Scenario-ID': `benchmark_scenario_${randomIntBetween(1, 5)}`,
      },
    });
    const duration = Date.now() - start;
    
    apiBenchmarks.ingest.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'ingest responds successfully': (r) => r.status === 200 || r.status === 202,
      'ingest response time acceptable': (r) => r.timings.duration < 200,
    });
  });
  
  group('Benchmark - Reports', () => {
    const start = Date.now();
    const res = http.get(`${API_V1}/reports?page=1&page_size=10`, params);
    const duration = Date.now() - start;
    
    apiBenchmarks.reports.add(duration);
    throughputCounter.add(1);
    
    check(res, {
      'reports responds': (r) => r.status === 200 || r.status === 401,
    });
  });
  
  // Simulate memory usage tracking (if available)
  if (__ENV.K6_CLOUD_TOKEN) {
    memoryUsage.add(randomIntBetween(100, 500)); // Simulated memory usage
  }
}

export function handleSummary(data) {
  const benchmarkResults = {
    test_id: `benchmark_${Date.now()}`,
    timestamp: new Date().toISOString(),
    duration: data.state.testRunDuration,
    vus: data.metrics.vus ? data.metrics.vus.values.value : 100,
    
    // Response time benchmarks
    benchmarks: {
      health: {
        p50: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values['p(50)'] : null,
        p95: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values['p(95)'] : null,
        avg: data.metrics.benchmark_health_ms ? data.metrics.benchmark_health_ms.values.avg : null,
      },
      auth: {
        p50: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values['p(50)'] : null,
        p95: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values['p(95)'] : null,
        avg: data.metrics.benchmark_auth_ms ? data.metrics.benchmark_auth_ms.values.avg : null,
      },
      scenarios_list: {
        p50: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values['p(50)'] : null,
        p95: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values['p(95)'] : null,
        avg: data.metrics.benchmark_scenarios_list_ms ? data.metrics.benchmark_scenarios_list_ms.values.avg : null,
      },
      ingest: {
        p50: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values['p(50)'] : null,
        p95: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values['p(95)'] : null,
        avg: data.metrics.benchmark_ingest_ms ? data.metrics.benchmark_ingest_ms.values.avg : null,
      },
    },
    
    // Throughput
    throughput: {
      total_requests: data.metrics.requests_total ? data.metrics.requests_total.values.count : 0,
      requests_per_second: data.metrics.requests_total ? 
        (data.metrics.requests_total.values.count / (data.state.testRunDuration / 1000)).toFixed(2) : 0,
    },
    
    // Error rates
    errors: {
      error_rate: data.metrics.http_req_failed ? data.metrics.http_req_failed.values.rate : 0,
      total_errors: data.metrics.http_req_failed ? data.metrics.http_req_failed.values.passes : 0,
    },
    
    // Pass/fail status
    passed: data.root_group.checks && data.root_group.checks.every(check => check.passes > 0),
  };
  
  return {
    'reports/benchmark-results.json': JSON.stringify(benchmarkResults, null, 2),
    stdout: `
========================================
   MOCKUPAWS v1.0.0 BENCHMARK RESULTS
========================================

Test Duration: ${(data.state.testRunDuration / 1000 / 60).toFixed(2)} minutes
Virtual Users: ${benchmarkResults.vus}

RESPONSE TIME BASELINES:
------------------------
Health Check:
  - p50: ${benchmarkResults.benchmarks.health.p50 ? benchmarkResults.benchmarks.health.p50.toFixed(2) : 'N/A'}ms
  - p95: ${benchmarkResults.benchmarks.health.p95 ? benchmarkResults.benchmarks.health.p95.toFixed(2) : 'N/A'}ms
  - avg: ${benchmarkResults.benchmarks.health.avg ? benchmarkResults.benchmarks.health.avg.toFixed(2) : 'N/A'}ms

Authentication:
  - p50: ${benchmarkResults.benchmarks.auth.p50 ? benchmarkResults.benchmarks.auth.p50.toFixed(2) : 'N/A'}ms
  - p95: ${benchmarkResults.benchmarks.auth.p95 ? benchmarkResults.benchmarks.auth.p95.toFixed(2) : 'N/A'}ms

Scenarios List:
  - p50: ${benchmarkResults.benchmarks.scenarios_list.p50 ? benchmarkResults.benchmarks.scenarios_list.p50.toFixed(2) : 'N/A'}ms
  - p95: ${benchmarkResults.benchmarks.scenarios_list.p95 ? benchmarkResults.benchmarks.scenarios_list.p95.toFixed(2) : 'N/A'}ms

Log Ingest:
  - p50: ${benchmarkResults.benchmarks.ingest.p50 ? benchmarkResults.benchmarks.ingest.p50.toFixed(2) : 'N/A'}ms
  - p95: ${benchmarkResults.benchmarks.ingest.p95 ? benchmarkResults.benchmarks.ingest.p95.toFixed(2) : 'N/A'}ms

THROUGHPUT:
-----------
Total Requests: ${benchmarkResults.throughput.total_requests}
Requests/Second: ${benchmarkResults.throughput.requests_per_second}

ERROR RATE:
-----------
Total Errors: ${benchmarkResults.errors.total_errors}
Error Rate: ${(benchmarkResults.errors.error_rate * 100).toFixed(2)}%

TARGET COMPLIANCE:
------------------
p95 < 200ms: ${benchmarkResults.benchmarks.health.p95 && benchmarkResults.benchmarks.health.p95 < 200 ? '✓ PASS' : '✗ FAIL'}
Error Rate < 1%: ${benchmarkResults.errors.error_rate < 0.01 ? '✓ PASS' : '✗ FAIL'}

Overall Status: ${benchmarkResults.passed ? '✓ PASSED' : '✗ FAILED'}

========================================
`,
  };
}
