#include <studio/program_info.hpp>
#include <studio/program_options.hpp>
#include <studio/simulator.hpp>
#include <osi/run.hpp>
#include <utils/config.hpp>
#include <utils/timeprof.hpp>
#include <utils/log.hpp>
#include <filesystem>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <iostream>
#if PLATFORM() == PLATFORM_WINDOWS()
#   pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") 
#endif

#if BUILD_RELEASE() == 1
static void save_crash_report(std::string const& crash_message)
{
    std::cout << "ERROR: " << crash_message << "\n";
    std::ofstream  ofile( get_program_name() + "_CRASH.txt", std::ios_base::app );
    ofile << crash_message << "\n";
}
#endif

int main(int argc, char* argv[])
{
#if BUILD_RELEASE() == 1
    try
#endif
    {
        LOG_INITIALISE(studio::get_program_name(), LSL_WARNING);
        studio::initialise_program_options(argc,argv);
        if (studio::get_program_options()->helpMode())
            std::cout << studio::get_program_options();
        else if (studio::get_program_options()->versionMode())
            std::cout << studio::get_program_version() << "\n";
        else
        {
            osi::run({
                .window_title = studio::get_program_name(),
                .resizable = true,
                .windowed = true,
                .icon_relative_path = "icon/rofibotstudio_icon.png",
                .font_relative_path = "font/Consolas.ttf",
                .constructor = []() { return std::make_unique<studio::Simulator>(); }
                });
            TMPROF_PRINT_TO_FILE(mak::get_program_name(),true);
        }
    }
#if BUILD_RELEASE() == 1
    catch(std::exception const& e)
    {
        try { save_crash_report(e.what()); } catch (...) {}
        return -1;
    }
    catch(...)
    {
        try { save_crash_report("Unknown exception was thrown."); } catch (...) {}
        return -2;
    }
#endif
    return 0;
}
