import dns from "dns";
import net from "net";

export async function checkHostnamePort(
    hostnamePort: string
): Promise<boolean> {
    try {
        // Split the input into hostname and port
        const [hostname, port] = hostnamePort.split(":");
        if (!hostname || !port) {
            return false; // Invalid format
        }

        // Resolve the hostname to an IP address
        const ip = (await resolveHostname(hostname)) as string;

        // Check if the port is open
        const portCheck = await checkPort(ip, parseInt(port, 10));

        return true; // Hostname:port is reachable
    } catch (err) {
        return false; // Any error means the hostname:port is not reachable
    }
}

function checkPort(ip: string, port: number): Promise<boolean> {
    return new Promise((resolve, reject) => {
        const socket = new net.Socket();

        socket.setTimeout(2000); // Set a timeout for the connection attempt

        socket.on("connect", () => {
            socket.destroy(); // Close the connection
            resolve(true); // Port is open
        });

        socket.on("timeout", () => {
            socket.destroy(); // Close the connection
            reject(new Error("Connection timed out")); // Port is not reachable
        });

        socket.on("error", (err: any) => {
            reject(new Error(`Unknown error: ${err}`)); // Handle non-Error types
        });

        socket.connect(port, ip);
    });
}

function resolveHostname(hostname: string) {
    return new Promise((resolve, reject) => {
        dns.lookup(hostname, (err, address) => {
            if (err) {
                reject(err);
            } else {
                resolve(address);
            }
        });
    });
}
