#include <maps/infra/yacare/include/yacare.h>
#include <maps/libs/cmdline/include/cmdline.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/libs/sql_chemistry/include/exceptions.h>
#include <maps/libs/vault_boy/include/secrets.h>
#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/libs/config/include/config.h>
#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/updater/lib/configuration.h>

#include <maps/libs/common/include/exception.h>

#include <memory>
#include <string>

namespace {

void errorReporter(const yacare::Request&, yacare::Response& resp)
{
    try {
        throw;
    }
    catch (const yacare::Error& e) {
        resp.setStatus(yacare::HTTPStatus::find(e.status()));
        resp << e.what();
        ERROR() << e;
    }
    catch (const maps::sql_chemistry::ObjectNotFound& e) {
        resp.setStatus(yacare::HTTPStatus::NotFound);
        resp << e.what();
        ERROR() << e;
    }
    catch (const maps::Exception& e) {
        resp.setStatus(yacare::HTTPStatus::InternalError);
        resp << e.what();
        ERROR() << e;
    }
    catch (const std::exception& e) {
        resp.setStatus(yacare::HTTPStatus::InternalError);
        resp << e.what();
        ERROR() << "Internal error: " << e.what();
    }
}


} // anonymous namespace

yacare::VirtualHost vhost{
    yacare::VirtualHost::SLB {
        "core-firmware-updater",
        "firmware-updater",
    },
    yacare::VirtualHost::FQDN {
        "core-firmware-updater.maps.yandex.net",
        "core-firmware-updater.testing.maps.yandex.net",
    },
};

YCR_SET_DEFAULT(vhost);

YCR_MAIN(argc, argv) try {
    maps::cmdline::Parser parser;
    auto configPath = parser.string("config")
            .help("path to configuration file");
    auto secretVersion = parser.string("secret-version")
            .help("version for secrets from yav.yandex-team.ru");

    parser.parse(argc, argv);

    INFO() << "Starting";
    auto cfg = secretVersion.defined()
               ? maps::fw_updater::config::Config(
            maps::vault_boy::loadContextWithYaVault(secretVersion),
            configPath)
               : maps::fw_updater::config::templateConfigFromCmdPath(configPath);

    maps::fw_updater::Configuration::swap(maps::fw_updater::makeConfiguration(std::move(cfg)));

    yacare::setErrorReporter(errorReporter);
    yacare::run();

    INFO() << "Shutting down";
    return EXIT_SUCCESS;
}
catch (const maps::Exception& e) {
    ERROR() << e;
    return EXIT_FAILURE;
}
catch (const std::exception& e) {
    ERROR() << e.what();
    return EXIT_FAILURE;
}
