import rawHttp from "k6/http";
import { Rate, Trend } from "k6/metrics";
import { fail, sleep } from "k6";
import {
  formatWaitForTimeoutError,
  normalizeWaitIntervalSeconds,
  readFileTimeoutBudget,
  remainingFileTimeoutMs,
  remainingFileTimeoutSeconds,
} from "../shared/file-timeout.mjs";
import { check, group } from "../runtime-src/k6/checks.js";

export { check, fail, group, sleep };
export { Rate, Trend };
export const http = rawHttp;

export function file(data, filename, contentType) {
  return rawHttp.file(data, filename, contentType);
}

export {
  emitArtifact,
} from "../runtime-src/k6/artifacts.js";
export {
  allMatch,
  contains,
  defaultOptions,
  isSorted,
  json,
  singleIterationOptions,
} from "../runtime-src/k6/checks.js";
export {
  createDalContext,
  openDb,
  truncate,
} from "../runtime-src/k6/dal.js";
export {
  createHttpClient,
  defaultOptions as httpDefaultOptions,
  getEnv,
  makeGetWithHeaders,
  makeRawReq,
  makeReq,
} from "../runtime-src/k6/http.js";

export function remainingTimeSeconds() {
  return remainingFileTimeoutSeconds(readFileTimeoutBudget(__ENV), Date.now());
}

export function waitFor(read, isReady, options = {}) {
  const intervalSeconds = normalizeWaitIntervalSeconds(options.intervalSeconds);
  const description = String(options.description || "condition").trim() || "condition";
  const budget = readFileTimeoutBudget(__ENV);
  let lastValue = read();

  while (true) {
    if (isReady(lastValue)) {
      return lastValue;
    }

    const remainingMs = remainingFileTimeoutMs(budget, Date.now());
    if (remainingMs <= 0) {
      break;
    }

    sleep(Math.min(intervalSeconds, remainingMs / 1000));
    lastValue = read();
  }

  throw new Error(formatWaitForTimeoutError(description, budget.fileTimeoutSeconds));
}
