import fetch from "cross-fetch";
import { LocalLogger, LogLevel, TracedFetch } from "../types";
import { traceIdHeaderName } from "../constants";

export default function newTracedFetch({
  timeoutMs,
  localLogger,
}: {
  timeoutMs: number;
  localLogger: LocalLogger;
}): TracedFetch {
  return async (traceId, url, requestInit) => {
    localLogger(LogLevel.Debug, `Fetching ${url}...`, {
      traceId,
      ...requestInit,
    });

    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), timeoutMs);

    try {
      const response = await fetch(url, {
        ...requestInit,
        headers: {
          ...requestInit.headers,
          [traceIdHeaderName]: traceId,
        },
        signal: controller.signal,
      });

      localLogger(LogLevel.Debug, `Successfully fetched ${url}`, {
        traceId,
        headers: { ...response.headers },
        status: response.status,
      });

      return response;
    } finally {
      clearTimeout(id);
    }
  };
}
