// In-memory, TTL-based cache for lines-of-code counts fetched from a project's
// `locEndpoint`. The endpoint is expected to return a plaintext integer.

type CacheEntry = { value: number | null; expiresAt: number };

const CACHE_TTL_MS = 1000 * 60 * 10; // 10 minutes
const cache = new Map<string, CacheEntry>();

async function fetchLocFromEndpoint(endpoint: string): Promise<number | null> {
  const cached = cache.get(endpoint);
  if (cached && cached.expiresAt > Date.now()) return cached.value;

  let value: number | null = null;
  try {
    const res = await fetch(endpoint, { signal: AbortSignal.timeout(5000) });
    if (res.ok) {
      const text = (await res.text()).trim();
      const parsed = Number.parseInt(text.replace(/[^0-9]/g, ""), 10);
      value = Number.isFinite(parsed) ? parsed : null;
    }
  } catch {
    value = null;
  }

  cache.set(endpoint, { value, expiresAt: Date.now() + CACHE_TTL_MS });
  return value;
}

/**
 * Resolve a project's line-of-code count: prefer the manually provided `loc`,
 * otherwise hit `locEndpoint` (cached in memory). Returns null when unknown.
 */
export async function resolveLoc(
  loc: number | null | undefined,
  locEndpoint: string | null | undefined,
): Promise<number | null> {
  if (typeof loc === "number") return loc;
  if (locEndpoint) return fetchLocFromEndpoint(locEndpoint);
  return null;
}
