// Journey: (login →) refresh → me → logout
//
// Endpoints exercised:
//   POST /api/v1/auth/login            (tried; gracefully skipped if ZITADEL v2
//                                       doesn't support password grant)
//   POST /api/v1/auth/token/refresh    (always exercised, using register tokens)
//   GET  /api/v1/members/me            (always)
//   POST /api/v1/auth/logout           (always)
//
// Why the conditional login? Modern ZITADEL v2 disables OAuth resource-owner
// password grant by default ({"error":"unsupported_grant_type"}), so the
// gateway's /auth/login → zitadel.VerifyPassword pipeline returns
// 502 + 28802000 in the default k6 environment. We probe login once; if it
// 5xx's we fall back to the registration tokens so the rest of the journey
// (refresh, me, logout) still gets coverage.
import { get, post, safeJson, checkEnvelope } from '../lib/http.js';
import { registerAndConfirm, refreshToken, logout } from '../lib/auth.js';
import { cfg } from '../lib/config.js';

export const options = {
  vus: 1,
  iterations: 1,
  thresholds: { checks: ['rate==1.0'] },
};

export default function () {
  const { identity, tokens: initial } = registerAndConfirm();

  // Probe login. If the env can't do password-grant, fall back to the
  // tokens we already have from registerAndConfirm.
  let tokens = initial;
  const loginRes = post('/api/v1/auth/login', {
    tenant_slug: cfg.tenantSlug,
    email: identity.email,
    password: identity.password,
  });
  if (loginRes.status === 200) {
    const body = checkEnvelope(loginRes, 'POST /auth/login (happy)');
    tokens = body.data;
    if (tokens.uid !== initial.uid) throw new Error('login returned different uid');
  } else {
    const body = safeJson(loginRes) || {};
    // Only the documented zitadel third-party failure is acceptable here.
    if (loginRes.status !== 502 || body.code !== 28802000) {
      throw new Error(
        `login: unexpected failure status=${loginRes.status} body=${loginRes.body}`,
      );
    }
    // proceed with register tokens; covered by /token/refresh below.
  }

  // refresh access token (works regardless of which token path we took)
  const refreshed = refreshToken({ refreshToken: tokens.refresh_token });
  if (!refreshed.access_token) throw new Error('refresh: missing access_token');

  // GET /me with the refreshed access token
  const me = checkEnvelope(
    get('/api/v1/members/me', { Authorization: `Bearer ${refreshed.access_token}` }),
    'GET /members/me (after refresh)',
  ).data;
  if (me.uid !== tokens.uid) throw new Error('me.uid mismatch');

  // logout
  logout({ accessToken: refreshed.access_token });
}
