#include "include/blackbox_client.h"

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

#include <algorithm>

#include <boost/lexical_cast.hpp>

namespace maps::mrc::blackbox_client {

std::optional<Uid> BlackboxClient::uidByLogin(const std::string& login) const
{
    auto maybeUserInfo = blackboxApi_.userInfoQuery()
                             .setRemoteAddress("127.0.0.1")
                             .setLogin(login)
                             .execute();
    if (maybeUserInfo.has_value()) {
        return boost::lexical_cast<Uid>(maybeUserInfo.value().uid());
    }
    return std::nullopt;
}

UidToLoginMap BlackboxClient::uidToLoginMap(Uids uids) const
{
    auto result = UidToLoginMap{};
    for (const auto& [uid, userInfo] : uidToUserInfoMap(std::move(uids), {})) {
        result.insert({uid, userInfo.login()});
    }
    return result;
}

UidToUserInfoMap BlackboxClient::uidToUserInfoMap(Uids uids, const QueryParams& params) const
{
    auto result = UidToUserInfoMap{};
    std::sort(uids.begin(), uids.end());
    auto it = std::unique(uids.begin(), uids.end());
    uids.erase(it, uids.end());
    auto batches = maps::common::makeBatches(
        uids, auth::BlackboxApi::UserInfoBatchQuery::MAX_BATCH_SIZE);
    for (const auto& batch : batches) {
        auto strUids = std::vector<std::string>{};
        for (auto uid : batch) {
            strUids.push_back(std::to_string(uid));
        }
        auto userInfos = blackboxApi_.userInfoBatchQuery()
                             .setRemoteAddress("127.0.0.1")
                             .setUids(strUids)
                             .setQueryParams(params)
                             .execute();
        for (const auto& userInfo : userInfos) {
            result.insert({boost::lexical_cast<Uid>(userInfo.uid()), userInfo});
        }
    }
    return result;
}

} // namespace maps::mrc::blackbox_client
