#!/usr/bin/env node
import { existsSync, readFileSync } from "node:fs";
import { homedir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";

const manager = detectPackageManager();

if (manager === "bun") {
  process.env.UNIVER_MANAGED_BY_BUN = "1";
  delete process.env.UNIVER_MANAGED_BY_NPM;
} else {
  process.env.UNIVER_MANAGED_BY_NPM = "1";
  delete process.env.UNIVER_MANAGED_BY_BUN;
}

startFirstOpenTelemetry();

await import("../internal/cli.js");

function startFirstOpenTelemetry() {
  try {
    const telemetryEntry = resolve(dirname(fileURLToPath(import.meta.url)), "../internal/product-telemetry.js");
    if (!telemetryEnabled(telemetryEntry) || firstOpenAlreadyAttempted()) {
      return;
    }
    const child = spawn(process.execPath, [telemetryEntry, "first-open"], {
      detached: true,
      env: process.env,
      stdio: "ignore",
      windowsHide: true
    });
    child.unref();
  } catch {
    // Product telemetry must never affect CLI startup.
  }
}

function telemetryEnabled(telemetryEntry) {
  if (!existsSync(telemetryEntry)) {
    return false;
  }
  try {
    const configPath = resolve(dirname(telemetryEntry), "product-telemetry.json");
    const config = JSON.parse(readFileSync(configPath, "utf8"));
    return typeof config.endpoint === "string" && config.endpoint.trim().length > 0;
  } catch {
    return false;
  }
}

function firstOpenAlreadyAttempted() {
  try {
    const statePath = resolveTelemetryStatePath();
    const state = JSON.parse(readFileSync(statePath, "utf8"));
    return state?.events?.cli_first_opened !== undefined;
  } catch {
    return false;
  }
}

function resolveTelemetryStatePath() {
  const configured = process.env.UNIVER_HOME?.trim();
  const root = configured && configured.length > 0 ? configured : join(homedir(), ".univer");
  return join(root, "telemetry", "state.json");
}

function detectPackageManager() {
  const versions = process.versions;
  if (typeof versions.bun === "string" && versions.bun.length > 0) {
    return "bun";
  }

  const userAgent = process.env.npm_config_user_agent ?? "";
  if (/\bbun\//u.test(userAgent)) {
    return "bun";
  }

  const execPath = process.env.npm_execpath ?? "";
  if (/(^|[/\\])bun(?:\.exe)?$/u.test(execPath)) {
    return "bun";
  }

  return "npm";
}
