import {
    NormalizedServerObject,
    ParsedDeploymentServiceConfig,
} from "@/src/types";
import execSSH from "@/src/utils/exec-ssh";
import serviceFlight from "@/src/utils/flight";
import grabTurboCiConfig from "@/src/utils/grab-turboci-config";

export default async function cronCheckServices() {
    const config = grabTurboCiConfig();

    for (let i = 0; i < config.services.length; i++) {
        const service = config.services[i];

        if (!service.servers) {
            continue;
        }

        for (let srv = 0; srv < service.servers.length; srv++) {
            const server = service.servers[srv];

            if (service.healthcheck) {
                const test = await healthcheck({ server, service });

                if (!test) {
                    console.log(
                        `Server ${server.private_ip} down. Restarting ...`,
                    );

                    const MAX_RETRIES = 5;
                    let retries = 0;

                    while (retries < MAX_RETRIES) {
                        console.log(`Retryig #${retries + 1} ...`);

                        await serviceFlight({
                            deployment: config,
                            servers: [server],
                            service,
                        });

                        await Bun.sleep(4000);

                        const retest = await healthcheck({ server, service });

                        if (retest) {
                            break;
                        } else {
                            retries++;
                        }
                    }
                }
            }
        }
    }
}

async function healthcheck({
    server,
    service,
}: {
    service: ParsedDeploymentServiceConfig;
    server: NormalizedServerObject;
}) {
    if (!service.healthcheck?.cmd || !server.private_ip) {
        return false;
    }

    const res = await execSSH({
        cmd: service.healthcheck.cmd,
        ip: server.private_ip,
    });

    const test = Boolean(res?.match(service.healthcheck.test));

    return test;
}
