/** @param {import(".").NS } ns */

export async function main(ns) {
    ns.disableLog('ALL');

    const nodeCostThreshold = ns.args.length > 0 ? ns.args[0] : 0.2;
    const upgradeCostThreshold = ns.args.length > 1 ? ns.args[1] : 0.1;
    const upgradeCount = ns.args.length > 2 ? ns.args[2] : 1;
    const helperBuyThreshold = ns.args.length > 3 ? ns.args[3] : 0.2;
    const nodeCap = 24;
    const levelCap = 200;
    const ramCap = 64;
    const coreCap = 16;
    const serverRAM = 32;
    ns.tprint(`Bot started {nodeCostThreshold: ${nodeCostThreshold}, upgradeCostThreshold: ${upgradeCostThreshold}, upgradeCount: ${upgradeCount}}`);

    

    while (true) {
        let currentMoney = ns.getServerMoneyAvailable("home");

        let nodePurchaseCost = ns.hacknet.getPurchaseNodeCost();
        let nodeCount = ns.hacknet.numNodes();

        if (nodeCount < nodeCap && nodePurchaseCost / Math.abs(currentMoney) < nodeCostThreshold) {
            ns.hacknet.purchaseNode();
            currentMoney = ns.getServerMoneyAvailable("home");
            ++nodeCount;
        }

        for (let index = 0; index < nodeCount; ++index) {
            let nodeStats = ns.hacknet.getNodeStats(index);

            if (nodeStats.level < levelCap && ns.hacknet.getLevelUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) {
                ns.hacknet.upgradeLevel(index, upgradeCount);
                currentMoney = ns.getServerMoneyAvailable("home");
            }

            if (nodeStats.ram < ramCap && ns.hacknet.getRamUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) {
                ns.hacknet.upgradeRam(index, upgradeCount);
                currentMoney = ns.getServerMoneyAvailable("home");
            }

            if (nodeStats.cores < coreCap && ns.hacknet.getCoreUpgradeCost(index, upgradeCount) / Math.abs(currentMoney) < upgradeCostThreshold) {
                ns.hacknet.upgradeCore(index, upgradeCount);
                currentMoney = ns.getServerMoneyAvailable("home");
            }
        }

        let serverCost = ns.getPurchasedServerCost(serverRAM);

        if (serverCost < currentMoney * helperBuyThreshold) {
            let newServer = ns.purchaseServer('home', serverRAM);
            if (newServer != '') {
                ns.tprint(`Bought a server`);
                ns.scp('grow-helper.js', newServer);
                ns.scp('constants.js', newServer);
                let execExitCode = ns.exec('grow-helper.js', newServer, 10, 20);
                ns.tprint(`Exec 'grow-helper.js' exit code: ${execExitCode}`);
            }
        }




        // let logFiles = ['hack-log.js', 'nuke-log.js'];

        // for (let index = 0; index < logFiles.length; index++) {
        //     const logFile = logFiles[index];
        //     let portData = ns.readPort(index + 1);
        //     if (portData != 'NULL PORT DATA') ns.write(logFile, portData, 'a');
        // }

        await ns.sleep(1000);
    }
}