module lunch.main;

import std.stdio;
import std.conv;
import std.path;
import std.file : readText, writeFile = write, exists, chdir, thisExePath;
import std.string;
import toml;
import lunch.conf;
import lunch.http;
import lunch.color;
import lunch.logger;
import lunch.update;
import lunch.launch;;


void _app(string config_toml)
{
    // Hide the cursor, reveal when exiting
    write("\33[?25l");
    scope (exit) write("\33[?25h");

    // Load default config
    wrapTOML(cast()config, config_toml.parseTOML());

    // Focus on exe
    chdir( thisExePath.dirName() );

    // Dynamicly load the config.
    if (config.app.load_config && exists(config.app.config_name))
    try
    {
        info("Loading external configuration");
        wrapTOML(cast()config, readText(config.app.config_name).parseTOML(), true);
    }
    catch (Exception e)
        warne("Failed loading external configuration", e);

    // Auto update
    if (config.app.auto_update)
        update();

    // Auto launch
    if (config.app.auto_launch)
        launch();

    // Show UI
    bool exit_ui = false;
    while (config.ui.enabled && !exit_ui)
    {
        void delegate()[] options;

        writeln("\x1B[3J\x1B[1;1H");
        writeln(config.ui.message);
        writeln();

        if (config.ui.launch)
        {
            options ~= () { launch(); };
            writefln("[%d] %s", options.length, config.ui.launch_label);
        }

        if (config.ui.update)
        {
            options ~= () { update(); };
            if (config.app.check_update && updateAvailable())
                writefln("[%d] %s", options.length, config.ui.update_avail_label);
            else
                writefln("[%d] %s", options.length, config.ui.update_label);
        }

        if (config.ui.config_dump)
        {
            options ~= () { writeFile(config.app.config_name, config_toml); };
            writefln("[%d] %s", options.length, config.ui.config_dump_label);
        }

        if (config.ui.exit)
        {
            options ~= () { exit_ui = true; };
            writefln("[%d] %s", options.length, config.ui.exit_label);
        }

        int opt;
        try
        {
            writef("\nSelect 1-%d : ", options.length);
            opt = readln().strip().to!int - 1;
        }
        catch (Exception ex)
        {
            continue;
        }

        if (opt >= 0 && opt < options.length)
            options[opt]();
    }

    info("Exit");
}


void app(string config_toml)
{
    try
    {
        _app(config_toml);
    }
    catch (Exception ex)
    {
        debug
        {
            writefln("\x1B[31m%s\x1B[0m", ex);
        }
        else
        {
            writeln("Critical error".red, ": ", ex.message.yellow);

            if (config.app.report_errors)
            {
                try
                {
                    writefln("Log reported to: %s", put(config.app.report_url, log).cyan);
                }
                catch (Exception) { }
            }

            version (Windows)
            {
                writeln("\nPress enter to exit...");
                readln();
            }
        }
    }
}
