#pragma once

#include <compare>
#include "docstream.h"

namespace NFusion {
    struct TMapReduceStreamConfig;
    struct IMapReduceQueue;

    struct TMapReducePosition {
        ui32 TableTimestamp = 0;
        ui64 TableRecord = 0;
        TMapReducePosition() = default;
        TMapReducePosition(ui64 tableRecord, ui32 tableTimestamp)
            : TableTimestamp(tableTimestamp),
            TableRecord(tableRecord) {
        }

        auto operator<=>(const TMapReducePosition&) const = default;
    };
    NRTYServer::TTimestampValue PositionToTimestamp(TMapReducePosition position);

    TMapReducePosition TimestampToPosition(NRTYServer::TTimestampValue timestamp);

    struct TMapReduceStream : TDocStream, SignalsHolder<> {
        using TBase = TDocStream;

        TMapReduceStream(const TDocFetcherModule& owner, const TMapReduceStreamConfig& config, const TRTYServerConfig& globalConfig, TLog& log);
        ~TMapReduceStream();

    protected:
        void OnDocStreamStart() override;
        void OnDocStreamStop() override;
        TDuration GetDelay() const override;
        bool IsExhausted() const override;
        void OnExhausted(TTimeToSleep& timeToSleep) override;
        TActionPtr GetDoc(TMap<TString, TString>& propsToLog, bool& /*skipSleepOnError*/) override;
        void ReportStatus(NJson::TJsonValue& status) override;

        TCommonDocStreamSignals* SignalsBase() const override {
            return SignalsHolder<>::Signals();
        }

    private:
        struct TMetrics : TCompositeMetric {
            TMetrics(const TString& /*name*/) {
            }
        };

        TActionPtr TryParseAction(const TString& value) const;

        const TMapReduceStreamConfig& Config;
        TAutoGlobal<TMetrics> Metrics;

        THolder<IMapReduceQueue> Queue;
    };
}
