#pragma once

#include <maps/libs/json/include/value.h>
#include <maps/libs/geolib/include/bounding_box.h>

#include <boost/functional/hash.hpp>

#include <unordered_map>

namespace maps::mrc::tools {

struct BboxHash {
    using value_type = geolib3::BoundingBox;

    size_t operator()(const geolib3::BoundingBox& that) const
    {
        std::size_t seed = 0;
        boost::hash_combine(seed, that.minX());
        boost::hash_combine(seed, that.maxX());
        boost::hash_combine(seed, that.minY());
        boost::hash_combine(seed, that.maxY());
        return seed;
    }
};

struct BboxEqualTo {
    using value_type = geolib3::BoundingBox;

    bool operator()(const geolib3::BoundingBox& lhs,
        const geolib3::BoundingBox& rhs) const
    {
        return lhs.lowerCorner() == rhs.lowerCorner()
            && lhs.upperCorner() == rhs.upperCorner();
    }
};

using BboxToHouseNumberMap = std::
    unordered_map<geolib3::BoundingBox, std::string, BboxHash, BboxEqualTo>;

using UrlToHouseNumbersMap
    = std::unordered_map<std::string, BboxToHouseNumberMap>;

UrlToHouseNumbersMap aggregateHouseNumbers(const json::Value&);

void dump(const UrlToHouseNumbersMap&, std::ostream&);

} // maps::mrc::tools
