import { Request, Response, NextFunction } from 'express';
import { TimeoutError } from '../httpErrors.js';

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Express {
    interface Locals {
      /**
       * An AbortSignal instantiated with the X-Unito-Operation-Deadline header. This header contains the timestamp
       * after which Unito will consider the operation to be timed out. You can use this signal to abort any
       * operation that would exceed this time frame.
       */
      signal?: AbortSignal;
    }
  }
}

const OPERATION_DEADLINE_HEADER = 'X-Unito-Operation-Deadline';

function extractOperationDeadline(req: Request, res: Response, next: NextFunction) {
  const operationDeadlineHeader = Number(req.header(OPERATION_DEADLINE_HEADER));

  if (operationDeadlineHeader) {
    // `operationDeadlineHeader` represents a timestamp in the future, in seconds.
    // We need to convert it to a number of milliseconds.
    const deadline = operationDeadlineHeader * 1000 - Date.now();

    if (deadline > 0) {
      res.locals.signal = AbortSignal.timeout(deadline);
    } else {
      throw new TimeoutError('Request already timed out upon reception');
    }
  }

  next();
}

export default extractOperationDeadline;
