#pragma once

#include "abstract.h"

#include <search/idl/meta.pb.h>

#include <util/generic/list.h>
#include <util/generic/vector.h>

class TSelfFlushLogFrame;
using TSelfFlushLogFramePtr = TIntrusivePtr<TSelfFlushLogFrame>;

class TRTYSimpleProtoReportBuilder: public ICustomReportBuilder {
private:
    using TGroup     = TList<NMetaProtocol::TDocument>;
    using TGrouping  = TMap<TString, TGroup>;
    using TGroupings = TMap<TString, TGrouping>;

private:
    IReportBuilderContext& Context;

    NMetaProtocol::TReport Report;
    TGroupings Groupings;
    TString Errors;
    TVector<TString> Events;
    ui64 ReportBytesSize = 0;
    bool Complete;

public:
    TRTYSimpleProtoReportBuilder(IReportBuilderContext& context)
        : Context(context)
        , Complete(true)
    {
    }

    virtual const IReportBuilderContext& GetContext() const override;
    virtual ui32 GetDocumentsCount() const override;
    virtual ui64 GetReportByteSize() const;
    virtual void AddDocument(NMetaProtocol::TDocument& doc) override;
    virtual void AddDocuments(TList<NMetaProtocol::TDocument> documents) override final;
    virtual void AddDocumentsToGroup(TList<NMetaProtocol::TDocument> docs, const TString& grouping, const TString& category) override final;
    virtual void AddDocumentToGroup(NMetaProtocol::TDocument& doc, const TString& grouping, const TString& category) override;
    virtual void AddReportProperty(const TString& propName, const TString& propValue) override;
    virtual void AddErrorMessage(const TString& msg) override;
    virtual void ConsumeReport(NMetaProtocol::TReport& report, const TString& source) override;
    virtual void MarkIncomplete(bool value = true) override;
    virtual void ScanReport(IScanner& scanner) const override;

    void ConsumeLog(const TSelfFlushLogFramePtr eventLog);
    void Finish(const ui32 httpCode);
    void Finish(NMetaProtocol::TReport&& report, const ui32 httpCode);

protected:
    inline IReportBuilderContext& GetContext() {
        return Context;
    }

    void InsertDocuments(NMetaProtocol::TReport& report);
    void InsertErrors(NMetaProtocol::TReport& report) const;
    void InsertEventLog(NMetaProtocol::TReport& report) const;
    void InsertMeta(NMetaProtocol::TReport& report, const ui32 httpCode) const;

    virtual void FinishImpl(NMetaProtocol::TReport& report, const ui32 httpCode);

private:
    ui32 GetDocumentsCount(const TGroupings& groupings) const;
    ui32 GetDocumentsCount(const TGrouping& grouping) const;
    ui32 GetDocumentsCount(const TGroup& group) const;
};
