import { stringifyError } from './IWNVWC3I.js';
import { resolveTypeVersions } from './55HL3CFD.js';
import { lockMany } from './FL2DFW3Y.js';
import { getImageUriForTool, getVolumeName } from './FQUILSS5.js';
import { AWS_REGION, AWS_ACCOUNT_ID, findToolByName, getChainTypeForTool, tools, versionsSatisfied } from './H7LPHZJT.js';
import { init_esm_shims, __name } from './4RNWLMHM.js';
import path from 'node:path';
import process from 'node:process';
import { $ } from 'zx';
import { getFullyQualifiedRepoRootPath } from '@layerzerolabs/common-node-utils';

// src/core/tool-executor.ts
init_esm_shims();
$.verbose = true;
$.stdio = [
  "inherit",
  "pipe",
  process.stderr
];
var mergeVolumes = /* @__PURE__ */ __name((defaultVolumes, userVolumes) => {
  const paths = new Set(userVolumes.map((volume) => volume.containerPath));
  return [
    ...userVolumes,
    ...defaultVolumes.filter((volume) => !paths.has(volume.containerPath))
  ];
}, "mergeVolumes");
async function ensureDockerImage(imageUri) {
  let output;
  try {
    output = await $`docker image ls ${imageUri}`.nothrow();
    if (output.stdout.includes(imageUri)) {
      console.info(`\u2705 Using cached Docker image: ${imageUri}`);
      return;
    }
    console.info("\u{1F4E5} Pulling Docker image from ECR:", 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:",
      `  - ECR image: ${imageUri} (pull failed)`,
      "",
      "\u{1F4A1} Solutions:",
      `  1. Authenticate with ECR: aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com`,
      "  2. Check if the image tag exists in ECR."
    ].join("\n"));
  }
  console.info(`\u2705 Successfully pulled: ${imageUri}`);
}
__name(ensureDockerImage, "ensureDockerImage");
async function executeToolCommand(command, args, { cwd, volumes: userVolumes, customEntrypoint: entrypoint, env: customEnvVars, script, publish, versions = {} }) {
  const tool = findToolByName(command);
  const type = getChainTypeForTool(command);
  if (!type) {
    throw new Error([
      `Tool '${command}' not found or no type configuration available.`,
      `Available tools: ${tools.map(({ name }) => name).join(", ")}`,
      `Try: lz-tool --list-versions to see all available tools`
    ].join("\n"));
  }
  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 ${command}`);
    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(type, versions)[command];
  if (!resolvedVersion) {
    throw new Error(`No version resolved for tool ${command}`);
  }
  console.info(`\u{1F527} ${command} version: ${resolvedVersion}`);
  if (tool.getSecondaryVersion) {
    try {
      const secondaryVersion = tool.getSecondaryVersion({
        cwd
      });
      if (!versionsSatisfied(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 = getImageUriForTool(tool.name, resolvedVersion);
  const workspaceRoot = await getFullyQualifiedRepoRootPath();
  const relativePath = path.relative(workspaceRoot, cwd);
  await ensureDockerImage(imageURI);
  if (entrypoint?.trim()) {
    console.info(`\u{1F527} Using custom entrypoint: ${entrypoint}`);
  }
  const envArgs = customEnvVars.map((envVar) => [
    "-e",
    `${envVar.name}=${envVar.value}`
  ]).flat();
  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,
    "-v",
    `${workspaceRoot}:/workspace`,
    "-w",
    `/workspace/${relativePath}`,
    ...publish ? [
      "-p",
      publish.trim()
    ] : [],
    ...volumes.map(getVolumeName).flatMap((volume) => [
      "-v",
      volume
    ]),
    ...entrypoint ? [
      "--entrypoint",
      entrypoint
    ] : [],
    imageURI,
    ...finalArgs
  ];
  const output = await lockMany(volumes.flatMap((volume) => volume.type === "isolate" && volume.locked ? [
    volume.name
  ] : []), () => $`docker ${dockerArgs}`.nothrow());
  if (output.exitCode) {
    throw new Error(`Failed to run Docker container (exit code: ${output.exitCode})`);
  }
  return output;
}
__name(executeToolCommand, "executeToolCommand");

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