"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 __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
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);

// src/open.ts
var open_exports = {};
__export(open_exports, {
  openBrowser: () => openBrowser
});
function openBrowser(url) {
  const browser = process.env.BROWSER || "";
  if (browser.toLowerCase().endsWith(".js")) {
    executeNodeScript(browser, url);
  } else if (browser.toLowerCase() !== "none") {
    const browserArguments = process.env.BROWSER_ARGS ? process.env.BROWSER_ARGS.split(" ") : [];
    startBrowserProcess(browser, browserArguments, url);
  }
}
function executeNodeScript(scriptPath, url) {
  const extraArguments = process.argv.slice(2);
  const child = (0, import_cross_spawn.default)(process.execPath, [scriptPath, ...extraArguments, url], {
    stdio: "inherit"
  });
  child.on("close", (code) => {
    if (code !== 0) {
      console.error(
        import_picocolors.default.red(
          `
The script specified as BROWSER environment variable failed.

${import_picocolors.default.cyan(
            scriptPath
          )} exited with code ${code}.`
        )
      );
    }
  });
}
async function startBrowserProcess(browser, browserArguments, url) {
  const preferredOSXBrowser = browser === "google chrome" ? "Google Chrome" : browser;
  const shouldTryOpenChromeWithAppleScript = process.platform === "darwin" && (!preferredOSXBrowser || supportedChromiumBrowsers.includes(preferredOSXBrowser));
  if (shouldTryOpenChromeWithAppleScript) {
    try {
      const ps = await execAsync("ps cax", {});
      const openedBrowser = preferredOSXBrowser && ps.includes(preferredOSXBrowser) ? preferredOSXBrowser : supportedChromiumBrowsers.find((b) => ps.includes(b));
      if (openedBrowser) {
        await execAsync(
          `osascript openChrome.applescript "${encodeURI(
            url
          )}" "${openedBrowser}"`,
          {
            cwd: `${__dirname}/../assets`
          }
        );
        return true;
      }
    } catch {
    }
  }
  if (process.platform === "darwin" && browser === "open") {
    browser = void 0;
  }
  try {
    const options = browser ? { app: { name: browser, arguments: browserArguments } } : {};
    (0, import_open.default)(url, options).catch(() => {
    });
    return true;
  } catch {
    return false;
  }
}
function execAsync(command, options) {
  return new Promise((resolve, reject) => {
    (0, import_node_child_process.exec)(command, options, (error, stdout) => {
      if (error) {
        reject(error);
      } else {
        resolve(stdout.toString());
      }
    });
  });
}
var import_node_child_process, import_cross_spawn, import_open, import_picocolors, supportedChromiumBrowsers;
var init_open = __esm({
  "src/open.ts"() {
    "use strict";
    import_node_child_process = require("child_process");
    import_cross_spawn = __toESM(require("cross-spawn"));
    import_open = __toESM(require("open"));
    import_picocolors = __toESM(require("picocolors"));
    supportedChromiumBrowsers = [
      "Google Chrome Canary",
      "Google Chrome Dev",
      "Google Chrome Beta",
      "Google Chrome",
      "Microsoft Edge",
      "Brave Browser",
      "Vivaldi",
      "Chromium"
    ];
  }
});

// src/index.ts
var src_exports = {};
__export(src_exports, {
  createConsoleApp: () => createConsoleApp
});
module.exports = __toCommonJS(src_exports);
var import_server = require("@wingconsole/server");
var import_express = __toESM(require("express"));

// src/analytics.ts
var import_analytics_node = __toESM(require("@segment/analytics-node"));
var createAnalytics = (options) => {
  let segment;
  const sessionId = Date.now();
  try {
    segment = new import_analytics_node.default({ writeKey: options.segmentWriteKey });
  } catch {
  }
  return {
    track(event, properties) {
      if (!segment) {
        return;
      }
      try {
        segment.track({
          anonymousId: options.anonymousId,
          event: event.toLowerCase().replaceAll(/\s/g, ""),
          properties,
          integrations: {
            "Actions Amplitude": {
              session_id: sessionId
            }
          }
        });
      } catch {
      }
    }
  };
};

// src/storage.ts
var import_node_crypto = require("crypto");
var import_node_fs = require("fs");
var os = __toESM(require("os"));
var import_node_path = __toESM(require("path"));
var WING_HOME_DIR = import_node_path.default.join(os.homedir(), ".wing");
var AnalyticsStorage = class {
  analyticsStorageDir;
  analyticsConfigFile;
  analyticsConfig;
  debug;
  constructor(props) {
    this.analyticsConfigFile = props?.configFile ?? import_node_path.default.join(import_node_path.default.join(WING_HOME_DIR, "wing-analytics-config.json"));
    this.analyticsStorageDir = props?.analyticsStorageDir ?? import_node_path.default.join(os.tmpdir(), "wing-analytics");
    this.debug = props?.debug;
    this.analyticsConfig = this.loadConfig();
  }
  /**
   * Reads the analytics config for the user's anonymous id,
   * if an id does not exist, one is generated and saved to disk
   *
   * @returns the anonymous id for the user
   */
  getAnonymousId() {
    let config = this.loadConfig();
    if (!config.anonymousId) {
      config.anonymousId = this.generateAnonymousId();
      this.saveConfig(config);
    }
    return config.anonymousId;
  }
  getRequireSignIn() {
    let config = this.loadConfig();
    if (config.requireSignIn == void 0) {
      config.requireSignIn = true;
      this.saveConfig(config);
    }
    return config.requireSignIn;
  }
  notifySignedIn() {
    let config = this.loadConfig();
    config.requireSignIn = false;
    this.saveConfig(config);
  }
  getEndpointWarningAccepted() {
    let config = this.loadConfig();
    if (config.endpointWarningAccepted == void 0) {
      config.endpointWarningAccepted = false;
      this.saveConfig(config);
    }
    return config.endpointWarningAccepted;
  }
  notifyEndpointWarningAccepted() {
    let config = this.loadConfig();
    config.endpointWarningAccepted = true;
    this.saveConfig(config);
  }
  generateAnonymousId() {
    return (0, import_node_crypto.randomBytes)(16).toString("hex");
  }
  /**
   * Retrieves the analytics config from disk, if one does not exist
   * a new one is created and saved to disk
   *
   * @returns the analytics config for the user
   */
  loadConfig() {
    try {
      const fileContents = (0, import_node_fs.readFileSync)(this.analyticsConfigFile, "utf8");
      return JSON.parse(fileContents);
    } catch (error) {
      if (this.debug) {
        console.log(`Error loading analytics config: ${error}`);
      }
      const analyticsConfig = {
        anonymousId: this.generateAnonymousId(),
        optOut: false
      };
      this.saveConfig(analyticsConfig);
      return analyticsConfig;
    }
  }
  /**
   * Saves the analytics config to disk
   *
   * @param config the analytics config to save to disk
   */
  saveConfig(config) {
    try {
      if (!(0, import_node_fs.existsSync)(WING_HOME_DIR)) {
        (0, import_node_fs.mkdirSync)(WING_HOME_DIR);
      }
      (0, import_node_fs.writeFileSync)(this.analyticsConfigFile, JSON.stringify(config));
    } catch (error) {
      if (this.debug) {
        console.log(`Error saving config file ${error}`);
      }
    }
  }
};

// src/index.ts
var MAX_ANALYTICS_STRING_LENGTH = 1024;
var staticDir = `${__dirname}/vite`;
var SEGMENT_WRITE_KEY = "JbpY9YH2totHTJjlb0qQjGFFdI2jWQDK";
var WING_DISABLE_ANALYTICS = process.env.WING_DISABLE_ANALYTICS;
var createConsoleApp = async (options) => {
  const analyticsStorage = new AnalyticsStorage();
  const analytics = SEGMENT_WRITE_KEY && !WING_DISABLE_ANALYTICS ? createAnalytics({
    anonymousId: analyticsStorage.getAnonymousId(),
    segmentWriteKey: SEGMENT_WRITE_KEY
  }) : void 0;
  analytics?.track("console_session_start");
  const server = await (0, import_server.createConsoleServer)({
    ...options,
    analyticsAnonymousId: analyticsStorage.getAnonymousId(),
    analytics,
    async requireSignIn() {
      if (options.requireSignIn !== void 0) {
        return options.requireSignIn;
      }
      const noSignIn = process.env.NO_SIGN_IN === "true";
      if (noSignIn) {
        return false;
      }
      return analyticsStorage.getRequireSignIn();
    },
    async notifySignedIn() {
      analyticsStorage.notifySignedIn();
    },
    async getEndpointWarningAccepted() {
      return analyticsStorage.getEndpointWarningAccepted();
    },
    async notifyEndpointWarningAccepted() {
      analyticsStorage.notifyEndpointWarningAccepted();
    },
    onExpressCreated(app) {
      app.use(import_express.default.static(staticDir));
      options.onExpressCreated?.(app);
    },
    onTrace(trace) {
      if (!analytics) {
        return;
      }
      if (trace.type !== "resource") {
        return;
      }
      if (options.requireAcceptTerms && !(0, import_server.isTermsAccepted)()) {
        return;
      }
      const resourceName = trace.sourceType.replace("@winglang/sdk.cloud.", "");
      if (!trace.data.message.includes("(")) {
        return;
      }
      const action = trace.data.message.slice(
        0,
        Math.max(0, trace.data.message.indexOf("("))
      );
      const properties = {
        message: trace?.data?.message?.slice(
          0,
          Math.max(0, MAX_ANALYTICS_STRING_LENGTH)
        ) || "",
        status: trace?.data?.status?.slice(
          0,
          Math.max(0, MAX_ANALYTICS_STRING_LENGTH)
        ) || "unknown",
        result: trace?.data?.result?.slice(
          0,
          Math.max(0, MAX_ANALYTICS_STRING_LENGTH)
        ) || "unknown"
      };
      analytics.track("console_resource_interact", {
        resource: resourceName,
        action,
        ...properties
      });
    },
    log: options.log ?? {
      info() {
      },
      error: console.error,
      warning() {
      },
      verbose() {
      }
    },
    config: options.config ?? {
      addEventListener(event, listener) {
      },
      removeEventListener(event, listener) {
      },
      get(key) {
        return void 0;
      },
      set(key, value) {
      }
    }
  });
  if (options.open) {
    const { openBrowser: openBrowser2 } = await Promise.resolve().then(() => (init_open(), open_exports));
    openBrowser2(`http://localhost:${server.port}/`);
  }
  return server;
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  createConsoleApp
});
