"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InternalPortCheck = exports.HostPortCheck = void 0;
const net_1 = require("net");
const common_1 = require("../../common");
class HostPortCheck {
    client;
    constructor(client) {
        this.client = client;
    }
    isBound(port) {
        return new Promise((resolve) => {
            const socket = new net_1.Socket();
            socket
                .setTimeout(1000)
                .on("error", () => {
                socket.destroy();
                resolve(false);
            })
                .on("timeout", () => {
                socket.destroy();
                resolve(false);
            })
                .connect(port, this.client.info.containerRuntime.host, () => {
                socket.end();
                resolve(true);
            });
        });
    }
}
exports.HostPortCheck = HostPortCheck;
class InternalPortCheck {
    client;
    container;
    isDistroless = false;
    commandOutputs = new Set();
    constructor(client, container) {
        this.client = client;
        this.container = container;
    }
    async isBound(port) {
        const portHex = port.toString(16).padStart(4, "0");
        const commands = [
            ["/bin/sh", "-c", `cat /proc/net/tcp* | awk '{print $2}' | grep -i :${portHex}`],
            ["/bin/sh", "-c", `nc -vz -w 1 localhost ${port}`],
            ["/bin/bash", "-c", `</dev/tcp/localhost/${port}`],
        ];
        const commandResults = await Promise.all(commands.map((command) => this.client.container.exec(this.container, command, { log: false })));
        const isBound = commandResults.some((result) => result.exitCode === 0);
        if (!isBound && common_1.log.enabled()) {
            const shellExists = commandResults.some((result) => result.exitCode !== 126);
            if (!shellExists) {
                if (!this.isDistroless) {
                    this.isDistroless = true;
                    common_1.log.error(`The HostPortWaitStrategy will not work on a distroless image, use an alternate wait strategy`, {
                        containerId: this.container.id,
                    });
                }
            }
            else {
                commandResults
                    .map((result) => ({ ...result, output: result.output.trim() }))
                    .filter((result) => result.exitCode !== 126 && result.output.length > 0)
                    .forEach((result) => {
                    if (!this.commandOutputs.has(this.commandOutputsKey(result.output))) {
                        common_1.log.trace(`Port check result exit code ${result.exitCode}: ${result.output}`, {
                            containerId: this.container.id,
                        });
                        this.commandOutputs.add(this.commandOutputsKey(result.output));
                    }
                });
            }
        }
        return isBound;
    }
    commandOutputsKey(output) {
        return `${this.container.id}:${output}`;
    }
}
exports.InternalPortCheck = InternalPortCheck;
//# sourceMappingURL=port-check.js.map