type RmLike = (path: string, opts: { recursive?: boolean; force?: boolean }) => Promise<void>;

function isRetryableRmError(err: unknown): boolean {
  if (!err || typeof err !== 'object') return false;
  const code = (err as { code?: unknown }).code;
  return code === 'EBUSY' || code === 'EPERM' || code === 'EACCES';
}

export async function rmWithRetries(
  rm: RmLike,
  targetPath: string,
  opts: { recursive?: boolean; force?: boolean },
  retries = 6,
): Promise<void> {
  let attempt = 0;
  // Windows: file locks/antivirus/indexers can cause transient EPERM/EBUSY.
  // We retry a few times before surfacing the error.
  // Delays: 20, 40, 80, 160, 320, 640ms (capped by retries).
  for (;;) {
    try {
      await rm(targetPath, opts);
      return;
    } catch (e) {
      attempt += 1;
      if (attempt > retries || !isRetryableRmError(e)) {
        throw e;
      }
      const delayMs = Math.min(800, 20 * 2 ** (attempt - 1));
      await new Promise((r) => setTimeout(r, delayMs));
    }
  }
}
