"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContainerPackager = void 0;
const constants_1 = require("../constants");
const types_1 = require("../errors/types");
const build_args_1 = require("./build-args");
const helpers_1 = require("./helpers");
const child_process_1 = require("child_process");
const fs_1 = require("fs");
/**
 * Detect container runtime synchronously.
 * Checks runtimes in CONTAINER_RUNTIMES order; returns the first available binary name.
 */
function detectContainerRuntimeSync() {
    for (const runtime of constants_1.CONTAINER_RUNTIMES) {
        const result = (0, child_process_1.spawnSync)('which', [runtime], { stdio: 'pipe' });
        if (result.status === 0) {
            const versionResult = (0, child_process_1.spawnSync)(runtime, ['--version'], { stdio: 'pipe' });
            if (versionResult.status === 0)
                return runtime;
        }
    }
    return null;
}
/**
 * Packager for Container agents.
 * Builds a container image locally and validates its size.
 */
class ContainerPackager {
    pack(spec, options = {}) {
        if (spec.build !== 'Container') {
            return Promise.reject(new types_1.PackagingError('ContainerPackager only supports Container build type.'));
        }
        const agentName = options.agentName ?? spec.name;
        const configBaseDir = options.artifactDir ?? options.projectRoot ?? process.cwd();
        const codeLocation = (0, helpers_1.resolveCodeLocation)(spec.codeLocation, configBaseDir);
        const dockerfilePath = (0, constants_1.getDockerfilePath)(codeLocation, spec.dockerfile);
        // Preflight: Dockerfile must exist
        if (!(0, fs_1.existsSync)(dockerfilePath)) {
            return Promise.reject(new types_1.PackagingError(`${spec.dockerfile ?? constants_1.DOCKERFILE_NAME} not found at ${dockerfilePath}. Container agents require a Dockerfile.`));
        }
        // Detect container runtime
        const runtime = detectContainerRuntimeSync();
        if (!runtime) {
            // No runtime available — skip local build validation (deploy will use CodeBuild)
            return Promise.resolve({
                artifactPath: '',
                sizeBytes: 0,
                stagingPath: codeLocation,
            });
        }
        // Build locally
        const imageName = `agentcore-package-${agentName}`;
        const buildResult = (0, child_process_1.spawnSync)(runtime, ['build', '-t', imageName, '-f', dockerfilePath, ...(0, build_args_1.getUvBuildArgs)(), codeLocation], {
            stdio: 'pipe',
        });
        if (buildResult.status !== 0) {
            return Promise.reject(new types_1.PackagingError(`Container build failed:\n${buildResult.stderr?.toString()}`));
        }
        // Validate size (1GB limit)
        const inspectResult = (0, child_process_1.spawnSync)(runtime, ['image', 'inspect', imageName, '--format', '{{.Size}}'], {
            stdio: 'pipe',
        });
        const sizeBytes = parseInt(inspectResult.stdout?.toString().trim() ?? '0', 10);
        if (sizeBytes > constants_1.ONE_GB) {
            const sizeMb = (sizeBytes / (1024 * 1024)).toFixed(2);
            return Promise.reject(new types_1.PackagingError(`Container image exceeds 1GB limit (${sizeMb}MB). ` +
                'Optimize your Dockerfile: use multi-stage builds, minimize dependencies, add .dockerignore.'));
        }
        return Promise.resolve({
            artifactPath: `${runtime}://${imageName}`,
            sizeBytes,
            stagingPath: codeLocation,
        });
    }
}
exports.ContainerPackager = ContainerPackager;
//# sourceMappingURL=container.js.map