#pragma once
#include <saas/library/yt/common/yt_blob.h>
#include <saas/tools/dump_fullarc_to_yt/params.pb.h>
#include <saas/library/sharding/sharding.h>
#include <saas/protos/rtyserver.pb.h>
#include <util/memory/blob.h>

class IFormatDumper {
public:
    virtual void ProcessMessage(const NRTYServer::TMessage& message) = 0;
    IFormatDumper(NYT::TTableWriter<NYT::TNode>* writer, NSaas::IShardDispatcher* shardDispatcher)
        : Writer(writer)
        , ShardDispatcher(shardDispatcher)
        , Progress(0) {
    }
    virtual ~IFormatDumper(){}
protected:
    NYT::TTableWriter<NYT::TNode>* Writer;
    NSaas::IShardDispatcher* ShardDispatcher;
    size_t Progress;
};

class TMessageDumper : public IFormatDumper {
public:
    TMessageDumper(NYT::TTableWriter<NYT::TNode>* writer, NSaas::IShardDispatcher* shardDispatcher)
        : IFormatDumper(writer, shardDispatcher) {
    }
    virtual void ProcessMessage(const NRTYServer::TMessage& message) override;
};

class TDebugDumper : public IFormatDumper {
public:
    TDebugDumper(NYT::TTableWriter<NYT::TNode>* writer, NSaas::IShardDispatcher* shardDispatcher)
        : IFormatDumper(writer, shardDispatcher) {
    }
    virtual void ProcessMessage(const NRTYServer::TMessage& message) override;
};

class TDirDumper : public IFormatDumper {
public:
    TDirDumper(NYT::TTableWriter<NYT::TNode>* writer, NSaas::IShardDispatcher* shardDispatcher)
        : IFormatDumper(writer, shardDispatcher) {
    }
    virtual void ProcessMessage(const NRTYServer::TMessage& message) override;
};

bool UnpackMessage(const TBlob& blob, NRTYServer::TMessage& message);

template <typename TArchiveIterator>
void ReadArchive(TArchiveIterator& input, IFormatDumper* dumper) {
    for (; input.IsValid(); input.Next()) {
        NRTYServer::TMessage message;
        if (UnpackMessage(input.GetDocument(), message)) {
            dumper->ProcessMessage(message);
        }
    }
}

TString GetShardIndex(const NRTYServer::TMessage& message, NSaas::IShardDispatcher& shardDispatcher);

THolder<NSaas::IShardDispatcher> CreateShardDispatcher(const NUtils::TParams& params);

TString GetLayerPrefix(const NUtils::TParams& params);

TString GetAnyLayerPrefix(const NUtils::TParams& params);
