import {App} from "./App";
import debug from "debug";
import {WebsocketApp} from "./WebsocketApp";
import {Database} from "./database/Database";
import {iTender} from "./iTender";
import {iTenderStatus} from "./iTenderStatus";
import {Utils} from "./Utils";
import {Settings} from "./Settings";
import Drink from "./database/Drink";
import {MyGPIO} from "./MyGPIO";
import {ContainerHelper} from "./ContainerHelper";
import {Mixer} from "./Mixer";
import {ArduinoProxy} from "./ArduinoProxy";

const log = debug("itender:server");

const app = new App();
const wsApp = new WebsocketApp();


(async () => {
    try {
        log("Starting...");
        Settings.loadSettings();


        await Database.connect();
        if( Settings.get("arduino_proxy_enabled") as boolean )
        {
            try {
                await ArduinoProxy.connect();
            } catch( e )
            {
                Settings.set("arduino_proxy_enabled",false);
                Settings.setupDone = false;
                log("Force iTender to setup, because proxy not connected!");
            }
        }
        //await test();
        await app.listen();
        await wsApp.listen();


        iTender.setStatus(iTenderStatus.STARTING);
        await Utils.sleep(2000);

        if (!Settings.setupDone) {
            iTender.setStatus(iTenderStatus.SETUP);
            log("iTender is not set up yet!");
        }


        log("Waiting for ready status...");
        await Utils.waitForReady();

        Settings.saveSettings();

        log("Check OK, starting...");
        await init();
        log("Init OK");
        setInterval(refresh, 1000 * 10);
        iTender.setStatus(iTenderStatus.READY);

    } catch (e) {
        console.error("---- ERROR ----");
        console.error(e);
        process.exit(-1);
    }
})();

/**
 * tst
 */
function init(): Promise<void> {

    return new Promise(async resolve => {
        log("Initializing...");
        await MyGPIO.setupPins();
        setTimeout(async () => {
            // Network
            await iTender.checkNetwork();
            let drinkCount = await Drink.countDocuments({});
            if (iTender.internetConnection && iTender.status == iTenderStatus.READY && drinkCount < 3) {
                console.log("No drinks in the database. - Try to refresh from server...")
                await iTender.refreshFromServer();
            }
        }, 1000 * 15);
        log("1");

        // Containers
        //await iTender.refreshContainers();
        await ContainerHelper.measureContainers();
        log("2");
        // Drinks
        await iTender.refreshDrinks();
        log("3");
        // Start auto checkup for stuck jobs
        await iTender.autoCheckup();
        log("4");
        resolve();
    });
}

function refresh(): Promise<void> {
    return new Promise(async resolve => {

        // Network
        await iTender.checkNetwork();

        // Below are refreshments of containers / drinks

        // If there is a current job, DO NOT REFRESH!
        if (iTender.status != iTenderStatus.READY)
            return;

        log("Refreshing...")
        //await iTender.refreshContainers(); Not needed because there is no change in containers?
        await ContainerHelper.measureContainers();
        //await iTender.refreshDrinks(); Not needed because there is no change in drinks?
    });
}