/// <reference path="../pb_data/types.d.ts" />
//
// Issue #18 — Reconcile the Entra (Azure) OIDC provider from the environment.
//
// The team_members→auth migration (pb_migrations/1781000000) is structure-only
// and runs exactly once. Provider CONFIGURATION lives here instead, so that:
//
//   * an environment whose migration applied while the ENTRA_* secrets were
//     absent gets its provider enabled on the next startup (no re-apply),
//   * rotating ENTRA_CLIENT_SECRET / changing the tenant only requires new env
//     values and a container restart,
//   * a fresh database gets its provider on the first cron tick right after
//     the migrations created the collection (onBootstrap fires BEFORE the
//     migrations run — there is no post-migration lifecycle hook in the JSVM,
//     hence the cron fallback).
//
// The reconciler compares before saving, so both hooks are cheap no-ops when
// everything is already in sync.

onBootstrap((e) => {
  e.next();
  const { reconcileEntraOidc } = require(`${__hooks}/utils.js`);
  // reconcileEntraOidc logs a warn-once itself when the ENTRA_* env is absent.
  console.log("entra_oidc reconcile (bootstrap): " + reconcileEntraOidc(e.app));
});

cronAdd("entraOidcReconcile", "* * * * *", () => {
  const { reconcileEntraOidc } = require(`${__hooks}/utils.js`);
  const result = reconcileEntraOidc($app);
  // Only log state changes — this tick runs every minute.
  if (result === "updated") {
    console.log("entra_oidc reconcile (cron): OIDC provider (re)configured from ENTRA_* env");
  }
});

// Entra does not always supply an `email` claim: the id_token only carries it
// when the account has a mail attribute (issue #24). The UPN in
// `preferred_username` is always present and equals the primary e-mail for
// Respellion organisation accounts, so fall back to it when it looks like a
// real address. Guest UPNs ("user_ext#EXT#@tenant...") fail the regex on
// purpose — those still get a clear validation error instead of a bogus email.
// The catch also surfaces the underlying OAuth2 failure in the container log,
// which PocketBase otherwise only writes to its internal logs database.
onRecordAuthWithOAuth2Request((e) => {
  const u = e.oAuth2User;
  if (u && !u.email) {
    const upn = String((u.rawUser && u.rawUser.preferred_username) || u.username || "").trim().toLowerCase();
    // `#` is RFC-valid in an e-mail local part, so guest UPNs
    // ("ext_user#EXT#@tenant.onmicrosoft.com") pass a naive e-mail check AND
    // PocketBase's own validation — exclude them explicitly.
    if (/^[^@\s#]+@[^@\s#]+\.[^@\s#]+$/.test(upn)) {
      u.email = upn;
      console.log("entra_oidc: email claim absent — falling back to UPN " + upn);
    }
  }
  try {
    e.next();
  } catch (err) {
    console.log("entra_oidc auth-with-oauth2 FAILED:", String(err));
    throw err;
  }
}, "team_members");
