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

using namespace flatbuffers64;

namespace maps::mrc::fb {

namespace {

auto unpack(const Vector<const CoveredSubPolyline*>& coveredSubpolylines)
{
    std::vector<CoveredSubPolyline> result;
    for (const auto& coveredSubpolyline : coveredSubpolylines) {
        result.push_back(*coveredSubpolyline);
    }
    return result;
}

auto unpack(const EdgeCoverage& edgeCoverage)
{
    return TEdgeCoverage{
        .coverageFraction = edgeCoverage.coverageFraction(),
        .actualizationDate = fromMilliseconds(edgeCoverage.actualizationDate()),
        .coveredSubpolylines = unpack(*edgeCoverage.coveredSubpolylines()),
        .cameraDeviation = db::CameraDeviation(edgeCoverage.cameraDeviation()),
        .privacy = decode(edgeCoverage.privacy())};
}

auto unpack(const Vector<Offset<EdgeCoverage>>& edgeCoverages)
{
    std::vector<TEdgeCoverage> result;
    for (size_t i = 0; i < edgeCoverages.size(); ++i) {
        result.push_back(unpack(*edgeCoverages.Get(i)));
    }
    return result;
}

auto unpack(const Edge& edge)
{
    return TEdge{.id = edge.id(), .coverages = unpack(*edge.coverages())};
}

}  // anonymous namespace

GraphReader::GraphReader(const std::string& path,
                         EMappingMode mappingMode)
    : storage_{common::blobFromFile(path, mappingMode)}
    , graph_{GetRoot<Graph>(storage_.Data())}
{
}

std::string_view GraphReader::version() const
{
    return decode(*graph_->version());
}

size_t GraphReader::edgesNumber() const
{
    return graph_->edges()->size();
}

TEdge GraphReader::edge(size_t index) const
{
    return unpack(*graph_->edges()->Get(index));
}

std::optional<TEdge> GraphReader::edgeById(uint32_t edgeId) const
{
    if (auto ptr = graph_->edges()->LookupByKey(edgeId)) {
        return unpack(*ptr);
    }
    return std::nullopt;
}

std::string_view GraphReader::mrcVersion() const
{
    return graph_->mrcVersion() ? decode(*graph_->mrcVersion())
                                : std::string_view{};
}

TSchemaVersion GraphReader::schemaVersion() const
{
    return graph_->schemaVersion();
}

}  // namespace maps::mrc::fb
