import { ay as dirname, p as networkFetch, h as getDefaultNetworkController } from "./fetch-virtual-server-BZi6n2Qk.js";
const DEFAULT_FLY_API_BASE_URL = "https://api.fly.io";
const FLY_CONFIG_PATH = "/home/user/.fly/config.yml";
let preparedFlyAuthPopup = null;
function normalizeLineEndings(value) {
  return value.replace(/\r\n/g, "\n");
}
function ensureTrailingNewline(value) {
  return value.endsWith("\n") ? value : `${value}
`;
}
function escapeRegExp(value) {
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function ensureParentDir(vfs, filePath) {
  const parent = dirname(filePath);
  if (!vfs.existsSync(parent)) {
    vfs.mkdirSync(parent, { recursive: true });
  }
}
function decodeYamlScalar(rawValue) {
  const trimmed = rawValue.trim();
  if (!trimmed) {
    return "";
  }
  if (trimmed === "null" || trimmed === "~") {
    return "";
  }
  if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
    try {
      if (trimmed.startsWith('"')) {
        return JSON.parse(trimmed);
      }
    } catch {
    }
    return trimmed.slice(1, -1);
  }
  return trimmed;
}
function encodeYamlScalar(value) {
  return JSON.stringify(value);
}
function readRawFlyConfig(vfs) {
  if (!vfs.existsSync(FLY_CONFIG_PATH)) {
    return "";
  }
  try {
    return normalizeLineEndings(vfs.readFileSync(FLY_CONFIG_PATH, "utf8"));
  } catch {
    return "";
  }
}
function readTopLevelYamlScalar(rawText, key) {
  const pattern = new RegExp(`^${escapeRegExp(key)}:\\s*(.*?)\\s*$`, "m");
  const match = rawText.match(pattern);
  if (!match) {
    return null;
  }
  return decodeYamlScalar(match[1] ?? "");
}
function upsertTopLevelYamlScalar(rawText, key, value) {
  const normalized = normalizeLineEndings(rawText);
  const lines = normalized ? normalized.split("\n") : [];
  const updatedLine = `${key}: ${encodeYamlScalar(value)}`;
  const nextLines = [];
  let replaced = false;
  for (const line of lines) {
    if (line.startsWith(`${key}:`)) {
      if (!replaced) {
        nextLines.push(updatedLine);
        replaced = true;
      }
      continue;
    }
    nextLines.push(line);
  }
  if (!replaced) {
    while (nextLines.length > 0 && nextLines[nextLines.length - 1] === "") {
      nextLines.pop();
    }
    nextLines.push(updatedLine);
  }
  return ensureTrailingNewline(nextLines.join("\n"));
}
function removeTopLevelYamlScalars(rawText, keys) {
  if (!rawText) {
    return "";
  }
  const keySet = new Set(keys);
  const nextLines = normalizeLineEndings(rawText).split("\n").filter((line) => !Array.from(keySet).some((key) => line.startsWith(`${key}:`)));
  while (nextLines.length > 0 && nextLines[nextLines.length - 1] === "") {
    nextLines.pop();
  }
  return nextLines.length > 0 ? ensureTrailingNewline(nextLines.join("\n")) : "";
}
function mapCliSession(raw) {
  return {
    id: typeof raw.id === "string" ? raw.id : "",
    authUrl: typeof raw.auth_url === "string" ? raw.auth_url : typeof raw.url === "string" ? raw.url : null,
    accessToken: typeof raw.access_token === "string" && raw.access_token ? raw.access_token : null,
    metadata: raw.metadata && typeof raw.metadata === "object" ? raw.metadata : void 0
  };
}
function withDefaultController() {
  return getDefaultNetworkController();
}
async function flyFetch(apiBaseUrl, pathname, init = {}) {
  return networkFetch(
    `${normalizeFlyApiBaseUrl(apiBaseUrl)}${pathname.startsWith("/") ? pathname : `/${pathname}`}`,
    init,
    withDefaultController()
  );
}
function delay(ms, signal) {
  if (ms <= 0) {
    return Promise.resolve();
  }
  return new Promise((resolve, reject) => {
    const handle = setTimeout(() => {
      signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
      resolve();
    }, ms);
    const onAbort = () => {
      clearTimeout(handle);
      signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
      reject(new DOMException("Aborted", "AbortError"));
    };
    if (signal == null ? void 0 : signal.aborted) {
      onAbort();
      return;
    }
    signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
  });
}
function normalizeFlyApiBaseUrl(value) {
  const trimmed = value == null ? void 0 : value.trim();
  if (!trimmed) {
    return DEFAULT_FLY_API_BASE_URL;
  }
  return trimmed.replace(/\/+$/, "") || DEFAULT_FLY_API_BASE_URL;
}
function readFlyConfig(vfs) {
  const rawText = readRawFlyConfig(vfs);
  const accessToken = readTopLevelYamlScalar(rawText, "access_token");
  const lastLogin = readTopLevelYamlScalar(rawText, "last_login");
  const appName = readTopLevelYamlScalar(rawText, "app");
  return {
    accessToken: (accessToken == null ? void 0 : accessToken.trim()) ? accessToken : null,
    lastLogin: (lastLogin == null ? void 0 : lastLogin.trim()) ? lastLogin : null,
    appName: (appName == null ? void 0 : appName.trim()) ? appName.trim() : null,
    rawText
  };
}
function readFlyAccessToken(vfs) {
  return readFlyConfig(vfs).accessToken;
}
function readFlyAppName(vfs) {
  return readFlyConfig(vfs).appName;
}
function writeFlyAccessToken(vfs, token, lastLogin = (/* @__PURE__ */ new Date()).toISOString()) {
  const normalizedToken = token.trim();
  const normalizedLastLogin = lastLogin.trim();
  let rawText = readRawFlyConfig(vfs);
  rawText = upsertTopLevelYamlScalar(rawText, "access_token", normalizedToken);
  rawText = upsertTopLevelYamlScalar(rawText, "last_login", normalizedLastLogin);
  ensureParentDir(vfs, FLY_CONFIG_PATH);
  vfs.writeFileSync(FLY_CONFIG_PATH, rawText);
}
function deleteFlyAccessToken(vfs) {
  if (!vfs.existsSync(FLY_CONFIG_PATH)) {
    return false;
  }
  const rawText = readRawFlyConfig(vfs);
  const updated = removeTopLevelYamlScalars(rawText, ["access_token", "last_login"]);
  if (!updated) {
    try {
      vfs.unlinkSync(FLY_CONFIG_PATH);
      return true;
    } catch {
      return false;
    }
  }
  if (updated === rawText) {
    return false;
  }
  ensureParentDir(vfs, FLY_CONFIG_PATH);
  vfs.writeFileSync(FLY_CONFIG_PATH, updated);
  return true;
}
function cancelPreparedFlyAuthPopup() {
  if (!preparedFlyAuthPopup) {
    return;
  }
  try {
    preparedFlyAuthPopup.close();
  } catch {
  }
  preparedFlyAuthPopup = null;
}
function openFlyAuthWindow(url) {
  var _a, _b;
  const popup = preparedFlyAuthPopup;
  preparedFlyAuthPopup = null;
  if (popup && !popup.closed) {
    try {
      popup.location.href = url;
      (_a = popup.focus) == null ? void 0 : _a.call(popup);
      return;
    } catch {
      try {
        popup.close();
      } catch {
      }
    }
  }
  try {
    (_b = window.open) == null ? void 0 : _b.call(window, url, "_blank");
  } catch {
  }
}
async function startFlyCliSession(apiBaseUrl, sessionName, options) {
  const response = await flyFetch(
    apiBaseUrl,
    "/api/v1/cli_sessions",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        name: sessionName,
        signup: options == null ? void 0 : options.signup,
        target: options == null ? void 0 : options.target,
        ...(options == null ? void 0 : options.metadata) ? { metadata: options.metadata } : {}
      })
    }
  );
  if (response.status !== 201) {
    throw new Error(`Fly CLI session request failed: ${response.status} ${response.statusText}`);
  }
  return mapCliSession(await response.json());
}
async function getFlyCliSessionState(apiBaseUrl, sessionId) {
  const response = await flyFetch(apiBaseUrl, `/api/v1/cli_sessions/${encodeURIComponent(sessionId)}`);
  if (response.status === 404) {
    throw new Error("Fly CLI session not ready");
  }
  if (!response.ok) {
    throw new Error(`Fly CLI session poll failed: ${response.status} ${response.statusText}`);
  }
  return mapCliSession(await response.json());
}
async function waitForFlyCliSessionToken(apiBaseUrl, sessionId, options) {
  var _a, _b;
  const startedAt = Date.now();
  const timeoutMs = (options == null ? void 0 : options.timeoutMs) ?? 15 * 60 * 1e3;
  const pollIntervalMs = (options == null ? void 0 : options.pollIntervalMs) ?? 1e3;
  while (Date.now() - startedAt < timeoutMs) {
    if ((_a = options == null ? void 0 : options.signal) == null ? void 0 : _a.aborted) {
      throw new DOMException("Aborted", "AbortError");
    }
    try {
      const state = await getFlyCliSessionState(apiBaseUrl, sessionId);
      if ((_b = state.accessToken) == null ? void 0 : _b.trim()) {
        return state.accessToken.trim();
      }
    } catch {
    }
    await delay(pollIntervalMs, options == null ? void 0 : options.signal);
  }
  throw new Error("Login expired, please try again");
}
function getFlyAuthorizationHeader(token) {
  const normalized = token.trim();
  if (/^(FlyV1|Bearer)\s+/i.test(normalized)) {
    return normalized;
  }
  for (const rawToken of normalized.split(",")) {
    const prefix = rawToken.trim().split("_", 1)[0];
    if (prefix === "fm1r" || prefix === "fm2") {
      return `FlyV1 ${normalized}`;
    }
  }
  return `Bearer ${normalized}`;
}
async function fetchFlyCurrentUser(apiBaseUrl, token) {
  var _a, _b;
  const response = await flyFetch(
    apiBaseUrl,
    "/graphql",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: getFlyAuthorizationHeader(token)
      },
      body: JSON.stringify({
        query: `
          query {
            viewer {
              ... on User {
                id
                email
              }
              ... on Macaroon {
                email
              }
            }
          }
        `
      })
    }
  );
  if (!response.ok) {
    throw new Error(`Failed to load Fly user: ${response.status} ${response.statusText}`);
  }
  const payload = await response.json();
  if ((_a = payload.errors) == null ? void 0 : _a.length) {
    throw new Error(payload.errors.map((entry) => entry.message).filter(Boolean).join(", ") || "Fly GraphQL error");
  }
  const viewer = (_b = payload.data) == null ? void 0 : _b.viewer;
  return {
    id: typeof (viewer == null ? void 0 : viewer.id) === "string" ? viewer.id : void 0,
    email: typeof (viewer == null ? void 0 : viewer.email) === "string" ? viewer.email : null
  };
}
export {
  writeFlyAccessToken as a,
  readFlyAppName as b,
  cancelPreparedFlyAuthPopup as c,
  deleteFlyAccessToken as d,
  fetchFlyCurrentUser as f,
  getFlyAuthorizationHeader as g,
  normalizeFlyApiBaseUrl as n,
  openFlyAuthWindow as o,
  readFlyAccessToken as r,
  startFlyCliSession as s,
  waitForFlyCliSessionToken as w
};
//# sourceMappingURL=fly-auth-y0soRCV1.js.map
