/**
 * Timeout utilities for operations
 */

/**
 * Create a timeout promise that rejects after specified time
 */
export function createTimeout(ms: number, message = 'Operation timed out'): Promise<never> {
  return new Promise((_, reject) => {
    setTimeout(() => reject(new Error(message)), ms);
  });
}

/**
 * Race a promise against a timeout
 */
export async function withTimeout<T>(
  promise: Promise<T>,
  timeoutMs: number,
  timeoutMessage = 'Operation timed out'
): Promise<T> {
  return Promise.race([
    promise,
    createTimeout(timeoutMs, timeoutMessage),
  ]);
}

/**
 * Create a timeout wrapper function
 */
export function timeout<T extends (...args: unknown[]) => Promise<unknown>>(
  fn: T,
  timeoutMs: number,
  timeoutMessage?: string
): T {
  return ((...args: Parameters<T>) => {
    return withTimeout(fn(...args) as Promise<ReturnType<T>>, timeoutMs, timeoutMessage);
  }) as T;
}

