"use strict";
/* Socket Lib - Built with esbuild */
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 mask_exports = {};
__export(mask_exports, {
  attachOutputMask: () => attachOutputMask,
  createKeyboardHandler: () => createKeyboardHandler,
  createOutputMask: () => createOutputMask,
  runWithMask: () => runWithMask
});
module.exports = __toCommonJS(mask_exports);
var import_child_process = require("child_process");
var import_readline = __toESM(require("readline"));
var import_spinner = require("../spinner.js");
var import_clear = require("./clear.js");
var import_stdout = require("./stdout.js");
const spinner = (0, import_spinner.getDefaultSpinner)();
function createOutputMask(options = {}) {
  const { showOutput = false } = options;
  return {
    isSpinning: !showOutput,
    outputBuffer: [],
    stderrCapture: "",
    stdoutCapture: "",
    verbose: showOutput
  };
}
function createKeyboardHandler(mask, child, options = {}) {
  const { message = "Running\u2026", toggleText = "to see full output" } = options;
  return (_str, key) => {
    if (key?.ctrl && key.name === "o") {
      mask.verbose = !mask.verbose;
      if (mask.verbose) {
        if (mask.isSpinning) {
          spinner.stop();
          mask.isSpinning = false;
        }
        (0, import_clear.clearLine)();
        if (mask.outputBuffer.length > 0) {
          console.log("--- Output (ctrl+o to hide) ---");
          mask.outputBuffer.forEach((line) => {
            (0, import_stdout.write)(line);
          });
        }
      } else {
        if (mask.outputBuffer.length > 0) {
          const lineCount = mask.outputBuffer.join("").split("\n").length + 1;
          for (let i = 0; i < lineCount; i += 1) {
            process.stdout.write("\x1B[1A\x1B[2K");
          }
        }
        (0, import_clear.clearLine)();
        mask.outputBuffer = [];
        if (!mask.isSpinning) {
          spinner.start(`${message} (ctrl+o ${toggleText})`);
          mask.isSpinning = true;
        }
      }
    } else if (key?.ctrl && key.name === "c") {
      child.kill("SIGTERM");
      if (process.stdin.isTTY) {
        process.stdin.setRawMode(false);
      }
      throw new Error("Process cancelled by user");
    }
  };
}
function attachOutputMask(child, options = {}) {
  return new Promise((resolve, reject) => {
    const { message = "Running\u2026" } = options;
    const mask = createOutputMask(options);
    if (mask.isSpinning && process.stdout.isTTY) {
      spinner.start(
        `${message} (ctrl+o ${options.toggleText || "to see full output"})`
      );
    }
    if (process.stdin.isTTY) {
      import_readline.default.emitKeypressEvents(process.stdin);
      process.stdin.setRawMode(true);
      const keypressHandler = createKeyboardHandler(mask, child, options);
      process.stdin.on("keypress", keypressHandler);
      child.on("exit", () => {
        if (process.stdin.isTTY) {
          process.stdin.setRawMode(false);
          process.stdin.removeListener("keypress", keypressHandler);
        }
      });
    }
    if (child.stdout) {
      child.stdout.on("data", (data) => {
        const text = data.toString();
        mask.stdoutCapture += text;
        if (options.filterOutput && !options.filterOutput(text, "stdout")) {
          return void 0;
        }
        if (mask.verbose) {
          (0, import_stdout.write)(text);
        } else {
          mask.outputBuffer.push(text);
          const lines = mask.outputBuffer.join("").split("\n");
          if (lines.length > 1e3) {
            mask.outputBuffer = [lines.slice(-1e3).join("\n")];
          }
        }
        return void 0;
      });
    }
    if (child.stderr) {
      child.stderr.on("data", (data) => {
        const text = data.toString();
        mask.stderrCapture += text;
        if (options.filterOutput && !options.filterOutput(text, "stderr")) {
          return void 0;
        }
        if (mask.verbose) {
          process.stderr.write(text);
        } else {
          mask.outputBuffer.push(text);
        }
        return void 0;
      });
    }
    child.on("exit", (code) => {
      if (process.stdin.isTTY) {
        process.stdin.setRawMode(false);
      }
      let finalCode = code || 0;
      if (options.overrideExitCode) {
        const overridden = options.overrideExitCode(
          finalCode,
          mask.stdoutCapture,
          mask.stderrCapture
        );
        if (overridden !== void 0) {
          finalCode = overridden;
        }
      }
      if (mask.isSpinning) {
        if (finalCode === 0) {
          spinner.successAndStop(`${message} completed`);
        } else {
          spinner.failAndStop(`${message} failed`);
          if (mask.outputBuffer.length > 0 && !mask.verbose) {
            console.log("\n--- Output ---");
            mask.outputBuffer.forEach((line) => {
              (0, import_stdout.write)(line);
            });
          }
        }
      }
      resolve(finalCode);
    });
    child.on("error", (error) => {
      if (process.stdin.isTTY) {
        process.stdin.setRawMode(false);
      }
      if (mask.isSpinning) {
        spinner.failAndStop(`${message} error`);
      }
      reject(error);
    });
  });
}
async function runWithMask(command, args = [], options = {}) {
  const {
    message = "Running\u2026",
    showOutput = false,
    toggleText = "to see output",
    ...spawnOptions
  } = options;
  const child = (0, import_child_process.spawn)(command, args, {
    stdio: ["inherit", "pipe", "pipe"],
    ...spawnOptions
  });
  return await attachOutputMask(child, { message, showOutput, toggleText });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  attachOutputMask,
  createKeyboardHandler,
  createOutputMask,
  runWithMask
});
