#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/include/detect_road_marking.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/batch.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/metadata.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/process.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/detect_road_marking/impl/frame.h>

namespace maps::mrc::eye {

DetectRoadMarking::DetectRoadMarking(const DetectRoadMarkingConfig& config)
    : BaseMrcWorkerWithConfig(config)
{}

void DetectRoadMarking::processBatch(const db::TIds& frameIds) {
    const auto lock = lockIfNeed();
    auto readTxn = getSlaveTxn();

    INFO() << "Load new batch";
    auto data = loadDetectRoadMarkingInputData(*readTxn, frameIds);
    auto& [frameById, panelByFrameId] = data;

    INFO() << "Frames in batch: " << frameById.size();
    INFO() << "Panel recognitions in batch: " << panelByFrameId.size();

    // оставляем только те frame'ы, у которых еще нет
    // recognition'ов дорожной разметки
    frameById = removeRecognizedFrames(*readTxn, std::move(frameById));
    db::eye::Recognitions recognitions
        = process(config_.yt, std::move(frameById), panelByFrameId);

    auto writeTxn = getMasterWriteTxn(*(config_.mrc.pool));
    db::eye::RecognitionGateway(*writeTxn).upsertx(recognitions);

    commitIfNeed(*writeTxn);
}

bool DetectRoadMarking::processBatchInLoopMode(size_t batchSize) {
    const auto lock = lockIfNeed();
    auto readTxn = getSlaveTxn();
    DetectRoadMarkingMetadataManager readMetadata(*readTxn);

    INFO() << "Load new batch";
    auto batch = loadDetectRoadMarkingBatch(
        *readTxn,
        readMetadata.getFrameTxnId(), readMetadata.getPanelTxnId(),
        batchSize
    );
    auto& [frameById, panelByFrameId] = batch.data;

    INFO() << "Frame txn id interval: "
           << "[" << batch.beginFrameTxnId << ", " << batch.endFrameTxnId << ")";
    INFO() << "Panel txn id interval: "
           << "[" << batch.beginPanelTxnId << ", " << batch.endPanelTxnId << ")";
    INFO() << "Frames in batch: " << frameById.size();
    INFO() << "Panel recognitions in batch: " << panelByFrameId.size();

    // оставляем только те frame'ы, у которых еще нет
    // recognition'ов дорожной разметки
    frameById = removeRecognizedFrames(*readTxn, std::move(frameById));
    db::eye::Recognitions recognitions
        = process(config_.yt, std::move(frameById), panelByFrameId);

    auto writeTxn = getMasterWriteTxn(*(config_.mrc.pool));
    db::eye::RecognitionGateway(*writeTxn).upsertx(recognitions);

    DetectRoadMarkingMetadataManager writeMetadata(*writeTxn);
    writeMetadata.updateFrameTxnId(batch.endFrameTxnId);
    writeMetadata.updatePanelTxnId(batch.endPanelTxnId);
    writeMetadata.updateTime();

    commitIfNeed(*writeTxn);

    return batch.beginFrameTxnId != batch.endFrameTxnId
        || batch.beginPanelTxnId != batch.endPanelTxnId;
}

} // namespace maps::mrc::eye
