module lunch.launch;

import std.file;
import std.path;
import std.array;
import std.process;
import luad.all;
import lunch.conf;
import lunch.logger;

version (Windows)
{
    pragma(lib, "User32");
    import core.sys.windows.windows;
}


void launch()
{
    string old_path = getcwd();
    scope (exit) chdir(old_path);

    version (Windows)
    {
        HWND hConsole = GetConsoleWindow();
        if (config.launcher.hide_when_running)
            ShowWindow(hConsole, SW_HIDE);

        scope (exit)
        if (config.launcher.hide_when_running)
            ShowWindow(hConsole, SW_SHOW);
    }

    if (!exists(config.launcher.workdir))
        error("Launcher workdir does not exist");

    if (config.launcher.use_script)
    {
        if (!exists(config.launcher.source_dir))
            error("Lua source dir does not exist");

        string source_dir = absolutePath(config.launcher.source_dir);
        auto lua_root = (string path) => chainPath(source_dir, path).array;

        if (!exists(lua_root(config.launcher.entry_file)))
            error("Lua entry file is missing");

        auto lua = new LuaState;
        lua.openLibs();

        auto orig_require = lua["require"].to!(LuaObject delegate(string mod));
        lua["require"] = (string mod)
        {
            auto work_dir = getcwd();
            chdir(source_dir);

            auto res = orig_require(mod);

            chdir(work_dir);
            return res;
        };

        chdir(config.launcher.workdir);
        try
        {
            lua.doFile(lua_root(config.launcher.entry_file));
        }
        catch (Exception ex)
        {
            errore("Lua script failed", ex);
        }
    }
    else
    {
        info("Launching");
        try
        {
            chdir(config.launcher.workdir);
            Pid pid = spawnProcess(config.launcher.command.dup);
            wait(pid);
        }
        catch (Exception ex)
        {
            errore("Failed to launch application", ex);
        }
    }
}
