import { describe, expect, it } from "vitest";
import {
  buildFileTimeoutEnv,
  DEFAULT_FILE_TIMEOUT_SECONDS,
  formatFileTimeoutBudgetError,
  formatWaitForTimeoutError,
  normalizeFileTimeoutSeconds,
  normalizeWaitIntervalSeconds,
  parseFileTimeoutOption,
  readFileTimeoutBudget,
  remainingFileTimeoutMs,
  remainingFileTimeoutSeconds,
} from "./file-timeout.mjs";

describe("file-timeout", () => {
  it("normalizes positive file timeout values", () => {
    expect(parseFileTimeoutOption("45")).toBe(45);
    expect(normalizeFileTimeoutSeconds(DEFAULT_FILE_TIMEOUT_SECONDS)).toBe(60);
    expect(() => parseFileTimeoutOption("0")).toThrow(
      'Invalid --file-timeout-seconds value "0"'
    );
    expect(() => normalizeFileTimeoutSeconds(0)).toThrow(
      "execution.fileTimeoutSeconds must be a positive integer."
    );
  });

  it("builds and reads runtime timeout budget env", () => {
    const env = buildFileTimeoutEnv(45, 1_000);
    expect(env).toEqual({
      TESTKIT_INTERNAL_FILE_TIMEOUT_SECONDS: "45",
      TESTKIT_INTERNAL_FILE_DEADLINE_MS: "46000",
    });

    expect(readFileTimeoutBudget(env)).toEqual({
      fileTimeoutSeconds: 45,
      deadlineMs: 46_000,
    });
  });

  it("computes remaining file timeout budget", () => {
    const budget = {
      fileTimeoutSeconds: 45,
      deadlineMs: 46_000,
    };

    expect(remainingFileTimeoutMs(budget, 40_000)).toBe(6_000);
    expect(remainingFileTimeoutMs(budget, 47_000)).toBe(0);
    expect(remainingFileTimeoutSeconds(budget, 44_500)).toBe(1.5);
  });

  it("normalizes wait intervals and timeout errors", () => {
    expect(normalizeWaitIntervalSeconds()).toBe(0.25);
    expect(normalizeWaitIntervalSeconds(0.5)).toBe(0.5);
    expect(() => normalizeWaitIntervalSeconds(0)).toThrow(
      "waitFor intervalSeconds must be a positive number."
    );
    expect(formatWaitForTimeoutError("cron worker pickup", 60)).toBe(
      "Timed out waiting for cron worker pickup before the 60s test file timeout"
    );
    expect(formatFileTimeoutBudgetError(60)).toBe(
      "Default runtime exceeded the 60s test file timeout"
    );
  });
});
