import { stringifyError } from './7XVJ6B7B.js';
import { resolveTypeVersions } from './ZO7WI2XS.js';
import { getImageUriForTool, getVolumeName } from './GPDDKHCR.js';
import { findWorkspaceRoot } from './WSGRZJVU.js';
import { findToolByName } from './KWRJPB5T.js';
import { lockMany } from './BAPGOHFS.js';
import { init_esm_shims, __name } from './6AHA7PAZ.js';
import { uniqBy } from 'es-toolkit';
import os from 'os';
import path from 'path';
import process from 'process';
import * as semver from 'semver';
import { $ } from 'zx';

// src/core/tool-executor.ts
init_esm_shims();
var getHostUserIds = /* @__PURE__ */ __name(() => {
  const userInfo = os.userInfo();
  if (userInfo.uid === -1 || userInfo.gid === -1) {
    return void 0;
  }
  return {
    uid: userInfo.uid,
    gid: userInfo.gid
  };
}, "getHostUserIds");
$.verbose = true;
$.stdio = [
  "inherit",
  "pipe",
  process.stderr
];
var mergeVolumes = /* @__PURE__ */ __name((defaultVolumes, userVolumes) => uniqBy([
  ...userVolumes,
  ...defaultVolumes
], (volume) => volume.containerPath), "mergeVolumes");
var resolveVolumePaths = /* @__PURE__ */ __name((volumes, workspaceRoot) => volumes.map((volume) => volume.type === "host" ? {
  ...volume,
  hostPath: path.resolve(workspaceRoot, volume.hostPath.replace(/^~/, os.homedir()))
} : volume), "resolveVolumePaths");
var ensureDockerImage = /* @__PURE__ */ __name(async (imageUri) => {
  let output;
  try {
    output = await $`docker image inspect --format {{.Id}} ${imageUri}`.nothrow();
    if (!output.exitCode) {
      console.info(`\u2705 Using cached Docker image: ${imageUri}`);
      return;
    }
    console.info("\u{1F4E5} Pulling Docker image from:", imageUri);
    output = await $`docker pull ${imageUri}`.nothrow();
  } catch (error) {
    throw new Error(`Failed to pull Docker image ${imageUri}: ${stringifyError(error)}`);
  }
  if (output.exitCode) {
    throw new Error([
      "Docker image not available:",
      `  - Image: ${imageUri} (pull failed)`,
      "  - Check if the image tag exists in image registry."
    ].join("\n"));
  }
  console.info(`\u2705 Successfully pulled: ${imageUri}`);
}, "ensureDockerImage");
async function executeToolCommand(context, toolName, args, { cwd, volumes: userVolumes, customEntrypoint: entrypoint, env: customEnvVars, script, publish, versions = {} }) {
  const tool = findToolByName(context, toolName);
  if (tool.preExecute) {
    await tool.preExecute(context, {
      cwd,
      args,
      volumes: userVolumes,
      env: customEnvVars,
      script,
      publish,
      versions
    });
  }
  const defaultVolumes = tool.defaultVolumes ?? [];
  const volumes = mergeVolumes(defaultVolumes, userVolumes);
  if (defaultVolumes.length > 0) {
    console.info(`\u{1F4E6} Using ${defaultVolumes.length} default cache volume(s) for ${tool.name}`);
    if (userVolumes.length > 0) {
      const overrides = userVolumes.filter((uv) => defaultVolumes.some((dv) => dv.containerPath === uv.containerPath));
      if (overrides.length > 0) {
        console.info(`\u{1F527} User volumes override ${overrides.length} default volume(s)`);
      }
    }
  }
  const resolvedVersion = resolveTypeVersions(context, versions)[tool.name];
  if (!resolvedVersion) {
    throw new Error(`No version resolved for tool ${tool.name}`);
  }
  console.info(`\u{1F527} ${tool.name} version: ${resolvedVersion}`);
  if (tool.getSecondaryVersion) {
    try {
      const secondaryVersion = await tool.getSecondaryVersion({
        cwd
      });
      if (!semver.satisfies(secondaryVersion, resolvedVersion)) {
        console.warn(`Warning: Local configuration version (${secondaryVersion}) differs from resolved version (${resolvedVersion})`);
      }
    } catch (error) {
      console.warn("Could not validate secondary version:", stringifyError(error));
    }
  }
  const imageUri = await getImageUriForTool(context, tool.name, resolvedVersion);
  const workspaceRoot = await findWorkspaceRoot(cwd);
  const relativePath = path.relative(workspaceRoot, cwd);
  await ensureDockerImage(imageUri);
  if (entrypoint?.trim()) {
    console.info(`\u{1F527} Using custom entrypoint: ${entrypoint}`);
  }
  const defaultEnv = tool.defaultEnv ?? [];
  const hasDockerSocketMount = volumes.some((v) => v.type === "host" && v.containerPath === "/var/run/docker.sock");
  const dockerSocketEnv = hasDockerSocketMount ? [
    {
      name: "HOST_CWD",
      value: cwd
    },
    {
      name: "HOST_WORKSPACE_ROOT",
      value: workspaceRoot
    }
  ] : [];
  const envArgs = uniqBy([
    ...customEnvVars,
    ...dockerSocketEnv,
    ...defaultEnv
  ], ({ name }) => name).flatMap(({ name, value }) => [
    "-e",
    `${name}=${value}`
  ]);
  const hostUserIds = getHostUserIds();
  const userIdEnvArgs = hostUserIds ? [
    "-e",
    `LOCAL_UID=${hostUserIds.uid}`,
    "-e",
    `LOCAL_GID=${hostUserIds.gid}`
  ] : [];
  console.info(`\u{1F464} Running container as UID:GID ${hostUserIds?.uid}:${hostUserIds?.gid}`);
  if (defaultEnv.length > 0) {
    console.info(`\u{1F30D} Using ${defaultEnv.length} default environment variable(s) for ${tool.name}`);
  }
  if (customEnvVars.length > 0) {
    console.info(`\u{1F30D} Using ${customEnvVars.length} custom environment variable(s)`);
  }
  let finalArgs;
  if (script && script.trim() !== "") {
    console.info(`\u{1F4DC} Executing custom script: ${script}`);
    finalArgs = [
      "bash",
      "-c",
      script
    ];
  } else {
    finalArgs = entrypoint === void 0 ? [
      tool.name,
      ...args
    ] : args;
  }
  const dockerArgs = [
    "run",
    ...tool.privileged ? [
      "--privileged"
    ] : [],
    "--rm",
    ...envArgs,
    ...userIdEnvArgs,
    "-v",
    `${workspaceRoot}:/workspace`,
    "-w",
    `/workspace/${relativePath}`,
    ...publish ? [
      "-p",
      publish.trim()
    ] : [],
    ...resolveVolumePaths(volumes, workspaceRoot).flatMap((volume) => [
      "-v",
      getVolumeName(volume)
    ]),
    ...entrypoint ? [
      "--entrypoint",
      entrypoint
    ] : [],
    imageUri,
    ...finalArgs
  ];
  const output = await lockMany(volumes.flatMap((volume) => volume.type === "isolate" && volume.locked ? [
    volume.name
  ] : []), async () => {
    const label = `\u23F1\uFE0F ${finalArgs.join(" ")}`;
    console.time(label);
    const result = await $`docker ${dockerArgs}`.nothrow();
    console.timeEnd(label);
    return result;
  });
  if (output.exitCode) {
    throw new Error(`Failed to run Docker container (exit code: ${output.exitCode})`);
  }
  return output;
}
__name(executeToolCommand, "executeToolCommand");

export { executeToolCommand };
//# sourceMappingURL=55NXWILT.js.map
//# sourceMappingURL=55NXWILT.js.map