#include <maps/wikimap/mapspro/services/mrc/libs/fb/impl/utility.h>
#include <maps/wikimap/mapspro/services/mrc/libs/fb/include/walk_objects_reader.h>

#include <util/generic/string.h>

using namespace flatbuffers64;

namespace maps::mrc::fb {

WalkObjectsReader::WalkObjectsReader(const std::string& fromDirectory,
                                     EMappingMode mappingMode)
    : storage_{common::blobFromFile(fromDirectory + "/" + WALK_OBJECTS_FILE,
                                    mappingMode)}
    , walkObjects_{GetRoot<WalkObjects>(storage_.Data())}
    , rtree_{fromDirectory + "/" + WALK_OBJECTS_RTREE_FILE, mappingMode}
{
    REQUIRE(decode(*walkObjects_->version()) == rtree_.version(),
            "inconsistent versions of "
                << WALK_OBJECTS_FILE << "(" << decode(*walkObjects_->version())
                << "), " << WALK_OBJECTS_RTREE_FILE << "(" << rtree_.version()
                << ")");
}

std::string_view WalkObjectsReader::version() const
{
    return decode(*walkObjects_->version());
}

size_t WalkObjectsReader::walkObjectsNumber() const
{
    return walkObjects_->walkObjects()->size();
}

db::TId WalkObjectsReader::id(size_t offset) const
{
    REQUIRE(offset < walkObjectsNumber(), "out of walk objects");
    return walkObjects_->walkObjects()->Get(offset)->id();
}

geolib3::Point2 WalkObjectsReader::pos(size_t offset) const
{
    REQUIRE(offset < walkObjectsNumber(), "out of walk objects");
    return getPos(*walkObjects_->walkObjects()->Get(offset));
}

std::optional<geolib3::Point2> WalkObjectsReader::posByWalkObjectId(
    db::TId walkObjectId) const
{
    if (auto ptr = walkObjects_->walkObjects()->LookupByKey(walkObjectId)) {
        return getPos(*ptr);
    }
    return std::nullopt;
}

}  // namespace maps::mrc::fb
