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

const { PRIVATE_USERNAME, PRIVATE_PASSWORD } = process.env;

/**
 * Constant-time string comparison to prevent timing attacks
 */
function constantTimeEqual(a: string, b: string): boolean {
  if (a.length !== b.length) {
    return false;
  }
  try {
    return crypto.timingSafeEqual(
      Buffer.from(a, 'utf8'),
      Buffer.from(b, 'utf8'),
    );
  } catch {
    return false;
  }
}

export function validateBasicAuth(req: Request): boolean {
  if (!PRIVATE_USERNAME || !PRIVATE_PASSWORD) {
    return false;
  }

  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return false;
  }

  try {
    const base64Credentials = authHeader.split(' ')[1];
    if (!base64Credentials) {
      return false;
    }

    const credentials = Buffer.from(base64Credentials, 'base64').toString(
      'ascii',
    );
    const colonIndex = credentials.indexOf(':');

    if (colonIndex === -1) {
      return false;
    }

    const username = credentials.substring(0, colonIndex);
    const password = credentials.substring(colonIndex + 1);

    if (
      constantTimeEqual(username, PRIVATE_USERNAME) &&
      constantTimeEqual(password, PRIVATE_PASSWORD)
    ) {
      (req as any).authenticated = true;
      return true;
    }
  } catch {
    // Invalid base64 or other parsing error
    return false;
  }

  return false;
}

export function checkBasicAuth(req: Request, res: Response): boolean {
  if (!PRIVATE_USERNAME || !PRIVATE_PASSWORD) {
    // Don't expose configuration status in production
    res.status(503).send('Service unavailable');
    return false;
  }

  const authHeader = req.headers.authorization;

  if (!authHeader || !authHeader.startsWith('Basic ')) {
    res.setHeader('WWW-Authenticate', 'Basic realm="Private Downloads"');
    res.status(401).send('Unauthorized');
    return false;
  }

  if (validateBasicAuth(req)) {
    return true;
  }

  res.setHeader('WWW-Authenticate', 'Basic realm="Private Downloads"');
  res.status(401).send('Unauthorized');
  return false;
}

export function isAuthenticated(req: Request): boolean {
  return !!(req as any).authenticated;
}
