#include <memory>
#include <csignal>
#include <corvusoft/restbed/resource.hpp>
#include <corvusoft/restbed/session.hpp>
#include <corvusoft/restbed/settings.hpp>
#include <corvusoft/restbed/service.hpp>
#include <spdlog/sinks/basic_file_sink.h>
#include "util/logging.hxx"
#include "server/server.hxx"
#include "index_html.h"
#include "favicon_svg.h"

std::shared_ptr<restbed::Service> g_service = nullptr;

const static restbed::Bytes index_html_bytes{index_html, index_html + index_html_len};
const static restbed::Bytes favicon_bytes{favicon_svg, favicon_svg + favicon_svg_len};

void signal_shutdown(const int) {
    spdlog::info("Recieved stop signal");
    g_service->stop();
}

int main() {
    auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("log.txt");
    spdlog::default_logger()->sinks().push_back(file_sink);
    spdlog::set_level(spdlog::level::trace);

    auto mrpc_resource = std::make_shared<restbed::Resource>();
    mrpc_resource->set_path("/mrpc");
    Server server{mrpc_resource};

#define mk_res(url) auto url##_resource = std::make_shared<restbed::Resource>(); \
    url##_resource->set_path("/" #url); \
    url##_resource->set_method_handler("POST", [&server](auto s){ server.url(s); })

    mk_res(download);
    mk_res(download_multi);
    mk_res(upload);
#undef mk_res

    auto index_resource = std::make_shared<restbed::Resource>();
    index_resource->set_path("/");
    index_resource->set_method_handler("GET", [](const std::shared_ptr<restbed::Session>& s){
        s->yield(
            200,
            index_html_bytes,
            std::multimap<std::string, std::string>{
                {"Content-Type", "text/html"},
                {"Content-Length", std::to_string(index_html_len)}
            }
        );
    });

    auto favicon_resource = std::make_shared<restbed::Resource>();
    favicon_resource->set_path("/favicon.svg");
    favicon_resource->set_method_handler("GET", [](const std::shared_ptr<restbed::Session>& s){
        s->yield(
            200,
            favicon_bytes,
            std::multimap<std::string, std::string>{
                {"Content-Type", "image/svg+xml"},
                {"Content-Length", std::to_string(favicon_svg_len)}
            }
        );
    });

    auto settings = std::make_shared<restbed::Settings>();
    settings->set_port(server.config.server_port);
    settings->set_default_header("Connection", "keep-alive");

    g_service = std::make_shared<restbed::Service>();
    g_service->set_logger(std::make_shared<logging::RestbedLogger>());
    g_service->set_signal_handler(SIGINT, signal_shutdown);
    g_service->set_signal_handler(SIGTERM, signal_shutdown);
    g_service->publish(mrpc_resource);
    g_service->publish(download_resource);
    g_service->publish(download_multi_resource);
    g_service->publish(upload_resource);
    g_service->publish(index_resource);
    g_service->publish(favicon_resource);
    g_service->start(settings);
    g_service.reset();

    return 0;
}
