/**
 * Federation routes — partner management and cross-IdP token verification.
 *
 * All management endpoints require the `admin:orgs` scope (enforced via opaMiddleware).
 * The verify endpoint requires any authenticated agent (enforced via authMiddleware only).
 *
 * Endpoints:
 *   POST   /federation/trust            → registerPartner  (admin:orgs)
 *   GET    /federation/partners         → listPartners     (admin:orgs)
 *   GET    /federation/partners/:id     → getPartner       (admin:orgs)
 *   PATCH  /federation/partners/:id     → updatePartner    (admin:orgs)
 *   DELETE /federation/partners/:id     → deletePartner    (admin:orgs)
 *   POST   /federation/verify           → verifyToken      (agents:read — any authenticated agent)
 *
 * Mount this router at `/api/v1` in app.ts so that paths become `/api/v1/federation/...`.
 */

import { Router, RequestHandler } from 'express';
import { FederationController } from '../controllers/FederationController.js';
import { asyncHandler } from '../utils/asyncHandler.js';

/**
 * Creates and returns the Express router for federation endpoints.
 * Mount at `${API_BASE}` (i.e. `/api/v1`) in app.ts.
 *
 * @param controller - The federation controller instance.
 * @param authMiddleware - JWT authentication middleware for the verify endpoint.
 * @param opaMiddleware - OPA authorization middleware for partner management endpoints.
 * @returns Configured Express router.
 */
export function createFederationRouter(
  controller: FederationController,
  authMiddleware: RequestHandler,
  opaMiddleware: RequestHandler,
): Router {
  const router = Router();

  // POST /federation/trust — register a new trusted partner (admin:orgs)
  router.post(
    '/federation/trust',
    authMiddleware,
    opaMiddleware,
    asyncHandler(controller.registerPartner.bind(controller)),
  );

  // GET /federation/partners — list all partners (admin:orgs)
  router.get(
    '/federation/partners',
    authMiddleware,
    opaMiddleware,
    asyncHandler(controller.listPartners.bind(controller)),
  );

  // GET /federation/partners/:id — get a specific partner (admin:orgs)
  router.get(
    '/federation/partners/:id',
    authMiddleware,
    opaMiddleware,
    asyncHandler(controller.getPartner.bind(controller)),
  );

  // PATCH /federation/partners/:id — update a partner (admin:orgs)
  router.patch(
    '/federation/partners/:id',
    authMiddleware,
    opaMiddleware,
    asyncHandler(controller.updatePartner.bind(controller)),
  );

  // DELETE /federation/partners/:id — delete a partner (admin:orgs)
  router.delete(
    '/federation/partners/:id',
    authMiddleware,
    opaMiddleware,
    asyncHandler(controller.deletePartner.bind(controller)),
  );

  // POST /federation/verify — verify a federated token (any authenticated agent)
  // Uses authMiddleware only — not OPA — so any agent with a valid token can call this.
  router.post(
    '/federation/verify',
    authMiddleware,
    asyncHandler(controller.verifyToken.bind(controller)),
  );

  return router;
}
