/**
 * Organization context middleware for SentryAgent.ai AgentIdP.
 * Sets the PostgreSQL session-level variable app.organization_id so that
 * Row-Level Security policies can filter data by organization.
 */

import { Request, Response, NextFunction, RequestHandler } from 'express';
import { Pool } from 'pg';

/**
 * Creates an Express middleware that propagates the caller's organization_id
 * into the current PostgreSQL session via SET.
 *
 * IMPORTANT: This middleware uses `SET app.organization_id = $1` (session-level),
 * NOT `SET LOCAL app.organization_id = $1` (transaction-level). SET LOCAL is only
 * effective inside an explicit BEGIN...COMMIT transaction block. Since most application
 * queries run outside explicit transactions using pool.query(), the session-level SET
 * is appropriate here. For full RLS isolation per-request in a connection pool, consider
 * using a dedicated client per request with explicit transaction wrapping.
 *
 * When `req.user.organization_id` is absent (backward-compatible tokens), the
 * middleware falls back to `DEFAULT_ORG_ID` env var (default: 'org_system').
 *
 * @param pool - The PostgreSQL connection pool.
 * @returns Express RequestHandler that sets the org context on each authenticated request.
 */
export function createOrgContextMiddleware(pool: Pool): RequestHandler {
  return async (req: Request, _res: Response, next: NextFunction): Promise<void> => {
    try {
      const defaultOrgId = process.env['DEFAULT_ORG_ID'] ?? 'org_system';
      const organizationId = req.user?.organization_id ?? defaultOrgId;

      await pool.query('SET app.organization_id = $1', [organizationId]);

      next();
    } catch (err) {
      next(err);
    }
  };
}
