#pragma once

#include <robot/library/oxygen/indexer/processor/pruning/interface.h>
#include <robot/library/oxygen/indexer/processor/protos/config.pb.h>

#include <util/thread/pool.h>
#include <util/generic/maybe.h>
#include <util/generic/set.h>

class THashSorterProcessor : public NOxygen::IPruningProcessor {
private:
    struct TDoc {
        size_t Hash;
        ui32 TmpDocId;
    };
    using TDocs = TVector<TDoc>;
    using TBadDocs = TSet<ui32>;

    struct TRemapResult {
        NOxygen::TDocIdMap DocIdMap;
        TVector<float> Ranks;
    };

private:
    const TAtomicSharedPtr<IThreadPool> TaskPool;
    const NOxygen::TProcessorPtr Slave;

    const TString TupleNameForUrl;
    const TString OutputPrefix;

    TDocs Docs;
    TBadDocs BadDocs;

public:
    THashSorterProcessor(
            const TAtomicSharedPtr<IThreadPool> taskPool,
            const NOxygen::TProcessorPtr slave,
            const TString& urlTupleName,
            const TString& outputPrefix = {}
    );
    ~THashSorterProcessor();

    TString GetClassName() const override {
        return "THashSorterProcessor";
    }

    // ITupleProcessor
    NOxygen::TTuplesUsageInfo GetRequiredTuples() const override;
    void Start() override;
    NThreading::TFuture<NOxygen::TReturnObjectContext> Process(NOxygen::TObjectContext objectContext, ui32 tmpObjectId) override;
    void Finish(const NOxygen::TDocIdMap* externalMap) override;

    ui64 GetVersion() const override;
    ui64 GetVersion(const TFsPath& directory) const override;

    // IPruningProcessor
    [[nodiscard]] NOxygen::TDocIdMap CreateDocIdMapAsInFinish(const NOxygen::TDocIdMap* externalMap) const override;

private:
    [[nodiscard]] TRemapResult CreateDocIdMapAsInFinish(TDocs& docs, const NOxygen::TDocIdMap* externalMap) const;
};
