"use strict";
/* Socket Lib - Built with esbuild */
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var internal_exports = {};
__export(internal_exports, {
  GIT_CACHE_MAX_SIZE: () => GIT_CACHE_MAX_SIZE,
  GIT_CACHE_TTL_MS: () => GIT_CACHE_TTL_MS,
  getCachedGitDiff: () => getCachedGitDiff,
  getGitDiffSpawnArgs: () => getGitDiffSpawnArgs,
  getGitPath: () => getGitPath,
  gitDiffCache: () => gitDiffCache,
  innerDiff: () => innerDiff,
  innerDiffSync: () => innerDiffSync,
  parseGitDiffStdout: () => parseGitDiffStdout,
  setCachedGitDiff: () => setCachedGitDiff,
  stableKey: () => stableKey
});
module.exports = __toCommonJS(internal_exports);
var import_which = require("../bin/which");
var import_output = require("../debug/output");
var import_matcher = require("../globs/matcher");
var import_normalize = require("../paths/normalize");
var import_array = require("../primordials/array");
var import_buffer = require("../primordials/buffer");
var import_json = require("../primordials/json");
var import_map_set = require("../primordials/map-set");
var import_object = require("../primordials/object");
var import_string = require("../primordials/string");
var import_spawn = require("../spawn/spawn");
var import_strip = require("../ansi/strip");
var import_repo = require("./repo");
const gitDiffCache = new import_map_set.MapCtor();
const GIT_CACHE_MAX_SIZE = 100;
const GIT_CACHE_TTL_MS = 2e3;
let _gitPath;
function getCachedGitDiff(key) {
  const entry = gitDiffCache.get(key);
  if (!entry) {
    return void 0;
  }
  if (Date.now() >= entry.expiresAt) {
    gitDiffCache.delete(key);
    return void 0;
  }
  gitDiffCache.delete(key);
  gitDiffCache.set(key, entry);
  return entry.result;
}
function getGitDiffSpawnArgs(cwd) {
  const resolvedCwd = cwd ? (0, import_repo.getCachedRealpath)(cwd) : (0, import_repo.getCwd)();
  return {
    all: [
      getGitPath(),
      ["status", "--porcelain"],
      {
        cwd: resolvedCwd
      }
    ],
    unstaged: [
      getGitPath(),
      ["diff", "--name-only"],
      {
        cwd: resolvedCwd
      }
    ],
    staged: [
      getGitPath(),
      ["diff", "--cached", "--name-only"],
      {
        cwd: resolvedCwd
      }
    ]
  };
}
function getGitPath() {
  if (_gitPath === void 0) {
    const resolved = (0, import_which.whichSync)("git", { nothrow: true });
    _gitPath = typeof resolved === "string" ? resolved : "git";
  }
  return _gitPath;
}
async function innerDiff(args, options) {
  const { cache = true, ...parseOptions } = { __proto__: null, ...options };
  const cacheKey = cache ? stableKey({ args, parseOptions }) : void 0;
  if (cache && cacheKey) {
    const result2 = getCachedGitDiff(cacheKey);
    if (result2) {
      return result2;
    }
  }
  let result;
  try {
    const spawnResult = await (0, import_spawn.spawn)(args[0], args[1], {
      ...args[2],
      stdioString: false
    });
    const stdout = (0, import_buffer.BufferIsBuffer)(spawnResult.stdout) ? spawnResult.stdout.toString("utf8") : (
      // String fallback only fires if spawn returns non-Buffer stdout.
      /* c8 ignore next */
      String(spawnResult.stdout)
    );
    const spawnCwd = typeof args[2]["cwd"] === "string" ? args[2]["cwd"] : void 0;
    result = parseGitDiffStdout(stdout, parseOptions, spawnCwd);
  } catch (e) {
    (0, import_output.debugNs)(
      "git",
      `Git command failed (${args[0]} ${args[1].join(" ")}): ${e.message}`
    );
    return [];
  }
  if (cache && cacheKey) {
    setCachedGitDiff(cacheKey, result);
  }
  return result;
}
function innerDiffSync(args, options) {
  const { cache = true, ...parseOptions } = { __proto__: null, ...options };
  const cacheKey = cache ? stableKey({ args, parseOptions }) : void 0;
  if (cache && cacheKey) {
    const result2 = getCachedGitDiff(cacheKey);
    if (result2) {
      return result2;
    }
  }
  let result;
  try {
    const spawnResult = (0, import_spawn.spawnSync)(args[0], args[1], {
      ...args[2],
      stdioString: false
    });
    const stdout = (0, import_buffer.BufferIsBuffer)(spawnResult.stdout) ? spawnResult.stdout.toString("utf8") : (
      // String fallback only fires if spawn returns non-Buffer stdout.
      /* c8 ignore next */
      String(spawnResult.stdout)
    );
    const spawnCwd = typeof args[2]["cwd"] === "string" ? args[2]["cwd"] : void 0;
    result = parseGitDiffStdout(stdout, parseOptions, spawnCwd);
  } catch (e) {
    (0, import_output.debugNs)(
      "git",
      `Git command failed (${args[0]} ${args[1].join(" ")}): ${e.message}`
    );
    return [];
  }
  if (cache && cacheKey) {
    setCachedGitDiff(cacheKey, result);
  }
  return result;
}
function parseGitDiffStdout(stdout, options, spawnCwd) {
  const defaultRoot = spawnCwd ? (0, import_repo.findGitRoot)(spawnCwd) : (0, import_repo.getCwd)();
  const {
    absolute = false,
    cwd: cwdOption = defaultRoot,
    porcelain = false,
    ...matcherOptions
  } = { __proto__: null, ...options };
  const path = (0, import_repo.getPath)();
  const cwd = cwdOption === defaultRoot ? defaultRoot : (0, import_repo.getCachedRealpath)(cwdOption);
  const rootPath = defaultRoot;
  let rawFiles = stdout ? (0, import_strip.stripAnsi)(stdout).split(/\r?\n/).map((line) => line.trimEnd()).filter((line) => line) : [];
  if (porcelain) {
    rawFiles = rawFiles.map((line) => {
      return line.length > 3 ? (0, import_string.StringPrototypeSubstring)(line, 3) : line;
    });
  }
  const files = absolute ? rawFiles.map((relPath2) => (0, import_normalize.normalizePath)(path.join(rootPath, relPath2))) : rawFiles.map((relPath2) => (0, import_normalize.normalizePath)(relPath2));
  if (cwd === rootPath) {
    return files;
  }
  const relPath = (0, import_normalize.normalizePath)(path.relative(rootPath, cwd));
  const matcher = (0, import_matcher.getGlobMatcher)([`${relPath}/**`], {
    ...matcherOptions,
    absolute,
    cwd: rootPath
  });
  const filtered = [];
  for (const filepath of files) {
    if (matcher(filepath)) {
      filtered.push(filepath);
    }
  }
  return filtered;
}
function setCachedGitDiff(key, result) {
  if (gitDiffCache.size >= GIT_CACHE_MAX_SIZE) {
    const oldest = gitDiffCache.keys().next().value;
    if (oldest !== void 0) {
      gitDiffCache.delete(oldest);
    }
  }
  gitDiffCache.set(key, { expiresAt: Date.now() + GIT_CACHE_TTL_MS, result });
}
function stableKey(value) {
  return (0, import_json.JSONStringify)(value, (_key, val) => {
    if (val && typeof val === "object" && !(0, import_array.ArrayIsArray)(val)) {
      const sorted = {};
      for (const k of (0, import_object.ObjectKeys)(val).sort()) {
        sorted[k] = val[k];
      }
      return sorted;
    }
    return val;
  });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  GIT_CACHE_MAX_SIZE,
  GIT_CACHE_TTL_MS,
  getCachedGitDiff,
  getGitDiffSpawnArgs,
  getGitPath,
  gitDiffCache,
  innerDiff,
  innerDiffSync,
  parseGitDiffStdout,
  setCachedGitDiff,
  stableKey
});
