"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var dashboard_exports = {};
__export(dashboard_exports, {
  openTypesenseDashboard: () => openTypesenseDashboard
});
module.exports = __toCommonJS(dashboard_exports);
var path = __toESM(require("path"));
var fs = __toESM(require("fs"));
var http = __toESM(require("http"));
var import_child_process = require("child_process");
var import_ui = require("../ui");
var import_archive = require("./archive");
const SERVER_STATE_FILE = "typesense-server.json";
const DASHBOARD_TARBALL = "https://github.com/bfritscher/typesense-dashboard/archive/refs/heads/gh-pages.tar.gz";
const STRIP_TAR_PREFIX = "typesense-dashboard-gh-pages/";
const STRIP_URL_PREFIX = "/typesense-dashboard";
function openBrowser(url) {
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
  try {
    (0, import_child_process.spawn)(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
  } catch {
  }
}
function downloadDashboard(cacheDir) {
  return (0, import_archive.extractTarGzFromUrl)(DASHBOARD_TARBALL, cacheDir, {
    stripPrefix: STRIP_TAR_PREFIX
  }).then(() => {
  });
}
const MIME = {
  ".html": "text/html; charset=utf-8",
  ".js": "application/javascript",
  ".mjs": "application/javascript",
  ".css": "text/css",
  ".json": "application/json",
  ".png": "image/png",
  ".svg": "image/svg+xml",
  ".ico": "image/x-icon",
  ".woff": "font/woff",
  ".woff2": "font/woff2",
  ".ttf": "font/ttf",
  ".map": "application/json"
};
function serveDashboard(cacheDir, port) {
  return http.createServer((req, res) => {
    let urlPath = (req.url ?? "/").split("?")[0];
    if (urlPath.startsWith(STRIP_URL_PREFIX)) {
      urlPath = urlPath.slice(STRIP_URL_PREFIX.length) || "/";
    }
    if (urlPath === "" || urlPath === "/") urlPath = "/index.html";
    const filePath = path.join(cacheDir, urlPath);
    if (!filePath.startsWith(cacheDir)) {
      res.writeHead(403);
      res.end();
      return;
    }
    let target = filePath;
    if (!fs.existsSync(target) || fs.statSync(target).isDirectory()) {
      target = path.join(cacheDir, "index.html");
    }
    if (!fs.existsSync(target)) {
      res.writeHead(404);
      res.end("Not found");
      return;
    }
    const ext = path.extname(target).toLowerCase();
    const mime = MIME[ext] ?? "application/octet-stream";
    res.writeHead(200, { "Content-Type": mime });
    fs.createReadStream(target).pipe(res);
  }).listen(port, "127.0.0.1");
}
function getFreePort() {
  return new Promise((resolve, reject) => {
    const srv = http.createServer().listen(0, "127.0.0.1", () => {
      const port = srv.address().port;
      srv.close(() => resolve(port));
    }).on("error", reject);
  });
}
async function openTypesenseDashboard(projectRoot) {
  const kirographDir = path.join(projectRoot, ".kirograph");
  const cacheDir = path.join(kirographDir, "typesense", "dashboard");
  const stateFile = path.join(kirographDir, SERVER_STATE_FILE);
  let apiPort = null;
  try {
    const state = JSON.parse(fs.readFileSync(stateFile, "utf8"));
    apiPort = state.apiPort;
  } catch {
  }
  const indexHtml = path.join(cacheDir, "index.html");
  if (!fs.existsSync(indexHtml)) {
    process.stdout.write(`  Downloading Typesense Dashboard (first time only)\u2026
`);
    try {
      await downloadDashboard(cacheDir);
      process.stdout.write(`  Dashboard ready.
`);
    } catch (err) {
      process.stdout.write(`  Dashboard download failed: ${String(err)}
`);
      return null;
    }
  }
  const dashboardPort = await getFreePort();
  const server = serveDashboard(cacheDir, dashboardPort);
  const url = `http://127.0.0.1:${dashboardPort}`;
  console.log(`
  ${import_ui.violet}${import_ui.bold}Typesense Dashboard${import_ui.reset}  ${import_ui.dim}(local)${import_ui.reset}`);
  console.log(`  ${import_ui.green}\u2713${import_ui.reset} Serving at ${import_ui.violet}${url}${import_ui.reset}`);
  console.log();
  console.log(`  Connect with:`);
  console.log(`  ${import_ui.dim}Node URL${import_ui.reset}  ${import_ui.violet}http://127.0.0.1:${apiPort ?? "???"}${import_ui.reset}`);
  console.log(`  ${import_ui.dim}API Key ${import_ui.reset}  ${import_ui.violet}kirograph-local${import_ui.reset}`);
  console.log();
  openBrowser(url);
  return server;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  openTypesenseDashboard
});
//# sourceMappingURL=dashboard.js.map
