import { Request, Response, NextFunction } from 'express';
import crypto from 'crypto';

// Constant-time compare; hashing first makes both buffers the same length.
const safeEqual = (a: string, b: string): boolean =>
  crypto.timingSafeEqual(
    crypto.createHash('sha256').update(a).digest(),
    crypto.createHash('sha256').update(b).digest(),
  );

// HTTP Basic auth for the Swagger UI (browser shows its own login prompt).
// Fails closed: without SWAGGER_USER / SWAGGER_PASSWORD the docs are not served.
const protectDocs = (req: Request, res: Response, next: NextFunction): void => {
  const user = process.env.SWAGGER_USER;
  const password = process.env.SWAGGER_PASSWORD;

  if (!user || !password) {
    res.status(503).send('API docs are disabled. Set SWAGGER_USER and SWAGGER_PASSWORD to enable them.');
    return;
  }

  const header = req.headers.authorization;
  if (header?.startsWith('Basic ')) {
    const decoded = Buffer.from(header.slice(6), 'base64').toString('utf8');
    const separator = decoded.indexOf(':');
    if (separator !== -1) {
      const userOk = safeEqual(decoded.slice(0, separator), user);
      const passwordOk = safeEqual(decoded.slice(separator + 1), password);
      if (userOk && passwordOk) {
        next();
        return;
      }
    }
  }

  res.set('WWW-Authenticate', 'Basic realm="API Docs", charset="UTF-8"');
  res.status(401).send('Authentication required');
};

export default protectDocs;
