/**
 * k6 Load Test — ForumZ Distributed Forum
 *
 * Tests a JWT-protected endpoint (/api/users/me) under sustained load.
 * Each request carries:
 *   - Authorization: Bearer <JWT>
 *   - Cookie: __Secure-Fgp=<fingerprint>   (OWASP token-sidejacking defense)
 *
 * Stages:
 *   0→30 s   ramp up to 50 VUs
 *   30→90 s  hold at 50 VUs  (main measurement window)
 *   90→120 s ramp down
 *
 * Run:
 *   k6 run load-test/k6-load-test.js
 *
 * With summary export:
 *   k6 run --out json=load-test/results.json load-test/k6-load-test.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 reqDuration = new Trend('req_duration_ms', true)

// ── Test config ───────────────────────────────────────────────────────────────
export const options = {
  stages: [
    { duration: '30s', target: 50 },   // ramp up
    { duration: '60s', target: 50 },   // sustained load
    { duration: '30s', target: 0  },   // ramp down
  ],
  thresholds: {
    http_req_failed:   ['rate<0.01'],   // <1 % errors
    http_req_duration: ['p(95)<500'],   // 95th percentile < 500 ms
    error_rate:        ['rate<0.01'],
  },
}

const BASE = 'http://localhost'

// ── Setup: register a dedicated load-test user; capture token AND fingerprint cookie ──
export function setup() {
  const username = `loadtest_${Date.now()}`
  const payload = JSON.stringify({
    username,
    email:    `${username}@example.com`,
    password: 'loadtest_pass_64bytes!!',
  })

  const res = http.post(`${BASE}/api/auth/register`, payload, {
    headers: { 'Content-Type': 'application/json' },
  })

  if (res.status !== 201) {
    throw new Error(`Setup failed (register): ${res.status} ${res.body}`)
  }

  const token = JSON.parse(res.body).token
  if (!token) throw new Error('No token in register response')

  // Extract the OWASP fingerprint cookie. Without it the JWT will be rejected.
  const fpCookies = res.cookies['__Secure-Fgp']
  if (!fpCookies || fpCookies.length === 0) {
    throw new Error('No __Secure-Fgp cookie in register response')
  }
  const fingerprint = fpCookies[0].value

  return { token, fingerprint }
}

// ── Main VU loop ──────────────────────────────────────────────────────────────
export default function (data) {
  const params = {
    headers: {
      'Authorization': `Bearer ${data.token}`,
      'Content-Type':  'application/json',
      // k6 doesn't share setup's cookie jar with VUs, so attach the fingerprint
      // cookie manually on every request.
      'Cookie':        `__Secure-Fgp=${data.fingerprint}`,
    },
    tags: { endpoint: 'me' },
  }

  // Hit JWT-protected endpoint
  const res = http.get(`${BASE}/api/users/me`, params)

  const ok = check(res, {
    'status 200':            (r) => r.status === 200,
    'served_by present':     (r) => r.headers['X-Served-By'] !== undefined,
    'body has served_by':    (r) => {
      try { return JSON.parse(r.body).served_by !== undefined } catch { return false }
    },
  })

  errorRate.add(!ok)
  reqDuration.add(res.timings.duration)

  sleep(0.1)  // 100 ms think time → ~9 req/s per VU ceiling
}

// ── Teardown ──────────────────────────────────────────────────────────────────
export function teardown() {
  console.log('Load test complete. Check results above.')
  console.log('Tip: run with --out json=load-test/results.json to export metrics.')
}
