#pragma once

#include <maps/wikimap/mapspro/services/mrc/drive/firmware_updater/libs/db/include/enums.h>

#include <maps/libs/enum_io/include/enum_io_fwd.h>
#include <maps/libs/log8/include/log8.h>
#include <maps/infra/yacare/include/yacare.h>

#include <string>

namespace {

template <typename T>
T parseEnumParam(const std::string& param)
{
    auto result = maps::enum_io::tryFromString<T>(param);
    if (!result) {
        throw std::bad_cast();
    }
    return *result;
}

} // namespace

using maps::fw_updater::db::Slot;

template <>
struct yacare::Parser<Slot>
{
    Slot operator()(const std::string& param) const
    {
        return parseEnumParam<Slot>(param);
    }
};

YCR_QUERY_PARAM(branch, std::string);
YCR_QUERY_PARAM(deviceid, std::string);
YCR_QUERY_PARAM(hardware, std::string);
YCR_QUERY_PARAM(id, uint64_t)
YCR_QUERY_PARAM(rollout_id, uint64_t);
YCR_QUERY_PARAM(slot, Slot);
YCR_QUERY_PARAM(version, std::string);

YCR_QUERY_CUSTOM_PARAM((), part, uint64_t)
{
    static constexpr uint64_t MAX_PART_NUMBER = 10000;

    if (yacare::impl::parseArg(dest, request, "part")) {
        if (0 < dest && dest <= MAX_PART_NUMBER) {
            return true;
        }
        throw yacare::errors::BadRequest() << "parameter `part` is out of range";
    }
    return false;
}

YCR_QUERY_CUSTOM_PARAM((), percent, uint16_t)
{
    static constexpr uint16_t MAX_PERCENT = 100;

    if (yacare::impl::parseArg(dest, request, "percent")) {
        if (0 < dest && dest <= MAX_PERCENT) {
            return true;
        }
        throw yacare::errors::BadRequest() << "parameter `percent` is out of range";
    }
    return false;
}

