import { IS_CLOUD } from '../constants/config.js';

/**
 * Creates middleware that injects relay helper functions onto req.
 * Must be applied AFTER authenticateToken.
 *
 * Security model:
 *   - All relay commands go through sendRelayCommand which validates action allowlist
 *   - Shell commands are restricted to known-safe prefixes (git, mkdir, rm, wmic)
 *   - Dangerous shell patterns (pipes to bash, backtick injection, etc.) are blocked
 *   - IP pinning: relay connection records the CLI's IP; only the authenticated user can send commands
 *   - The relay token is validated at WebSocket connect time; commands flow only to the token owner's machine
 *
 * Adds to req:
 *   - req.isCloud: boolean — true when running on Railway/Vercel/Render
 *   - req.hasRelay(): boolean — true when user's machine is connected
 *   - req.sendRelay(action, payload, timeout): Promise — send command to user's machine
 *   - req.requireRelay(): returns false + sends 503 if cloud mode and no relay connected
 */
export function createRelayMiddleware(hasActiveRelay, sendRelayCommand, withRetry) {
  return (req, res, next) => {
    const userId = Number(req.user?.id);
    req.isCloud = IS_CLOUD;
    req.hasRelay = () => hasActiveRelay(userId);
    // Retry transient relay failures (opencode pattern: exponential backoff)
    req.sendRelay = (action, payload, timeout) =>
      withRetry(() => sendRelayCommand(userId, action, payload, null, timeout || 15000), { maxRetries: 2 });

    // Helper: return 503 if cloud mode and no relay connected
    req.requireRelay = () => {
      if (IS_CLOUD && !hasActiveRelay(userId)) {
        res.status(503).json({
          error: 'Machine not connected',
          message: 'Run "uc connect" on your local machine to use this feature.',
          code: 'RELAY_NOT_CONNECTED'
        });
        return false;
      }
      return true;
    };

    next();
  };
}
