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



/**
 * remove write log ✓
 * loop
 *  get all servers
 *  nuke if possible
 *      send scripts hack, grow weaken
 *  backdoor factions
 *  buy grow servers
 *  start helpers if not running include home //remove from hacknet
 *      grow if needed
 *      weaken if needed
 *      hack if no grow or weaken
 *  do simple hack
 *      check if money available
 *      check threads
 *      run hack 
 *      run grow to recover
 *      run weaken if security too high
 *  buy hack tools
 */


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

    async function writeLog(type, obj) {
        let timeNow = new Date();
        let year = timeNow.getFullYear().toString().substring(2);
        let month = (timeNow.getMonth() < 9 ? '0' : '') + (timeNow.getMonth() + 1);
        let day = (timeNow.getDate() < 10 ? '0' : '') + timeNow.getDate();
        let hour = (timeNow.getHours() < 10 ? '0' : '') + timeNow.getHours();
        let minute = (timeNow.getMinutes() < 10 ? '0' : '') + timeNow.getMinutes();
        let second = (timeNow.getSeconds() < 10 ? '0' : '') + timeNow.getSeconds();
        let timestamp = `${year}.${month}.${day}_${hour}:${minute}:${second}`;
        ns.print(`${type}_${timestamp} = ${obj};`);

        if (['ERROR', 'TERMINAL'].indexOf(type) != -1) ns.tprint(`${type}_${timestamp} = ${obj};`);
    }

    async function runNuke(server) {
        let serverStatus = analyzeServer(server);
        await writeLog('ANALYZE', `{server: "${server}", status: ${JSON.stringify(serverStatus)}}`);

        if (!serverStatus.rootAccess) {
            if (serverStatus.nukeAvailable) {
                await writeLog('NUKE', `"Nuking ${server}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"`);
                for (let i = 0; i < maxPortsToHack(); ++i) { // TODO: change to try/catch
                    switch (EXPLOITS[i]) {
                        case 'BruteSSH.exe':
                            ns.brutessh(server);
                            break;

                        case 'FTPCrack.exe':
                            ns.ftpcrack(server);
                            break;

                        case 'relaySMTP.exe':
                            ns.relaysmtp(server);
                            break;

                        case 'HTTPWorm.exe':
                            ns.httpworm(server);
                            break;

                        case 'SQLInject.exe':
                            ns.sqlinject(server);
                            break;

                    }
                }
                ns.nuke(server);
            }
            // TODO: if faction > backdoor
        }
    }
    async function runHack(server) {
        let script = 'simple-hack.js';

        let serverStatus = analyzeServer(server);

        if (serverStatus.rootAccess) {
            if (!ns.fileExists(script, 'home')) {
                await writeLog('ERROR', `"Script '${script}' doesn't exist!"`);
                // return -3;
            }
            ns.scp(script, server, 'home');

            let serverMaxRam = ns.getServerMaxRam(server);
            let serverUsedRam = ns.getServerUsedRam(server);
            let serverFreeRam = serverMaxRam - serverUsedRam;
            let scriptRam = ns.getScriptRam(script, server);
            let maxThreads = Math.floor(serverFreeRam / scriptRam);

            let a = ns.scriptRunning(script, server);
            if (!a) {
                if (maxThreads == 0) {
                    // await writeLog('ERROR', `"Not enough ram to run '${script}' on '${server}', ${scriptRam}/${serverFreeRam}!"`);
                    return -4;
                }

                let execExitCode = ns.exec(script, server, maxThreads, server);

                if (!execExitCode) {
                    // await writeLog('ERROR', `"Exec error running script '${script} on '${server}!"`);
                    return -5;
                }
                else {
                    return execExitCode;
                }
            } else {
                // await writeLog('ERROR', `"Hack already running on ${server}"`);
                return 0;
            }
        }

        return -6;
    }

    function scanServer(currentServer, previousServer = currentServer) {
        let availableServers = ns.scan(currentServer);
        let result = [];

        for (let i = 0; i < availableServers.length; ++i) {
            let nextServer = availableServers[i];

            if (nextServer != currentServer && nextServer != previousServer) {
                result.concat(scanServer(nextServer, currentServer));
            }
        }

        return [currentServer].concat(result);
    }

    while (true) {
        let network = scanServer('home');

        await ns.sleep(100);
    }
}