/**
 * k6 load test — Token Issuance
 *
 * Scenario : POST /api/v1/token  (OAuth2 client_credentials grant)
 * VUs      : 1000
 * Duration : 60 seconds
 * Thresholds:
 *   p95 response time < 500 ms
 *   HTTP error rate   < 1 %
 *
 * Usage:
 *   BASE_URL=http://localhost:3000 \
 *   CLIENT_ID=your-client-id      \
 *   CLIENT_SECRET=your-secret     \
 *   k6 run tests/load/token-issuance.js
 */

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';

// ── Custom metrics ─────────────────────────────────────────────────────────────
const errorRate = new Rate('error_rate');
const tokenIssuanceDuration = new Trend('token_issuance_duration_ms', true);

// ── Configuration ──────────────────────────────────────────────────────────────
export const options = {
  vus: 1000,
  duration: '60s',
  thresholds: {
    http_req_duration: ['p(95)<500'],
    error_rate: ['rate<0.01'],
  },
};

const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';
const CLIENT_ID = __ENV.CLIENT_ID || 'load-test-client-id';
const CLIENT_SECRET = __ENV.CLIENT_SECRET || 'load-test-client-secret';

// ── Default function (executed per VU iteration) ───────────────────────────────
export default function tokenIssuance() {
  const url = `${BASE_URL}/api/v1/token`;

  // OAuth2 client_credentials grant — application/x-www-form-urlencoded body
  const payload = {
    grant_type: 'client_credentials',
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET,
    scope: 'agents:read agents:write',
  };

  const params = {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Accept: 'application/json',
    },
    timeout: '10s',
  };

  const response = http.post(url, payload, params);

  tokenIssuanceDuration.add(response.timings.duration);

  const success = check(response, {
    'status is 200': (r) => r.status === 200,
    'response has access_token': (r) => {
      try {
        const body = JSON.parse(r.body);
        return typeof body.access_token === 'string' && body.access_token.length > 0;
      } catch {
        return false;
      }
    },
    'token_type is Bearer': (r) => {
      try {
        const body = JSON.parse(r.body);
        return body.token_type === 'Bearer';
      } catch {
        return false;
      }
    },
    'response time < 500ms': (r) => r.timings.duration < 500,
  });

  errorRate.add(!success);

  // Minimal think-time — token issuance is typically called without delays
  sleep(0.05);
}
