#pragma once

#include "stream.h"
#include "mapreduce.h"

#include <saas/library/daemon_base/metrics/metrics.h>
#include <saas/library/index_snapshot/snapshot_manager.h>

#include <util/system/event.h>

struct TRTYServerConfig;

namespace NFusion {
    struct TSnapshotStreamConfig;

    enum class EGroupFetchStatus {
        Completed = 0,
        Partial = 1,
        Failed = 2,
        NothingToFetch = 3
    };

    class TSnapshotStream : public TBaseStream, public IStopCondition
    {
    public:
        TSnapshotStream(const TDocFetcherModule& owner, const TSnapshotStreamConfig& config, const TRTYServerConfig& globalConfig, TLog& log);
        virtual ~TSnapshotStream();

        bool Stopped() const override;
        const IStopCondition& Interruptable() const {
            return *this;
        }

    protected: // TBaseStream
        void OnStreamStart() override;
        void OnStreamBeforeStop() override;
        void OnStreamStop() override;
        TTimeToSleep DoStreamIteration() final;
        TDuration GetDelay() const override;
        IThreadFactory* GetThreadPool() override;

    protected:
        // NMessenger::IMessageProcessor
        virtual bool Process(IMessage* message) override;

    private: //IThreadLoop
        TTimeToSleep OnException() final;

    private:
        void InitTimestamp();
        void InitSearch();
        void UpdateSearch();
        EGroupFetchStatus FetchResource(const IIndexSnapshotManager::TShardResource& resource);
        EGroupFetchStatus FetchLatestAvailableResource(const IIndexSnapshotManager::TShardResources& resources);
        EGroupFetchStatus FetchResourceGroup(TInstant groupTimestamp, const IIndexSnapshotManager::TShardResources& resources);
        EGroupFetchStatus FetchLatestAvailableResourceGroup(const IIndexSnapshotManager::TGroupedShardResources& resources);
        bool ShouldSkipPosition(TMapReducePosition) const;
        void SetLastFetchedTimestamp(TInstant t);
        void SetLastFetchedPosition(TMapReducePosition t);

    private:
        const TRTYServerConfig& RTYServerConfig;
        const TSnapshotStreamConfig& SnapshotStreamConfig;
        THolder<IIndexSnapshotManager> SnapshotManager;
        TInstant LastFetchedTimestamp;
        TMapReducePosition LastFetchedPosition;
        TManualEvent StopEvent;
    };
}
