#pragma once

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

#include <library/cpp/http/misc/httpcodes.h>

#include <util/datetime/base.h>
#include <util/generic/string.h>
#include <library/cpp/cgiparam/cgiparam.h>
#include <util/generic/buffer.h>

enum ERTYSearchResult {
    SR_OK,
    SR_NOT_FOUND
};

class TRequestParams;
class TSearchRequestData;

class IReportBuilderContext {
public:
    virtual ~IReportBuilderContext() {}
    virtual const TCgiParameters& GetCgiParameters() const = 0;
    virtual const TSearchRequestData& GetRequestData() const = 0;
    virtual const TRequestParams& GetRP() const = 0;
    virtual TInstant GetRequestStartTime() const = 0;
    virtual long GetRequestedPage() const = 0;

    virtual void MakeSimpleReply(const TBuffer& buf, int code = HTTP_OK) = 0;
    virtual void AddReplyInfo(const TString& key, const TString& value) = 0;
    virtual void Print(const TStringBuf& data) = 0;
};

class ISimpleReportBuilder {
public:
    virtual ~ISimpleReportBuilder() = default;
    virtual void AddDocument(NMetaProtocol::TDocument& doc) = 0;
    virtual void AddDocuments(TList<NMetaProtocol::TDocument> docs) = 0;
};

class ICustomReportBuilder : public ISimpleReportBuilder {
public:
    class IScanner {
    public:
        virtual ~IScanner() {}

        virtual void operator()(const NMetaProtocol::TDocument& doc, const TString& grouping, const TString& category) = 0;
        virtual void operator()(const TString& key, const TString& value) = 0;
    };

public:
    virtual const IReportBuilderContext& GetContext() const = 0;
    virtual ui32 GetDocumentsCount() const = 0;

    virtual void AddDocumentToGroup(NMetaProtocol::TDocument& doc, const TString& grouping, const TString& category) = 0;
    virtual void AddDocumentsToGroup(TList<NMetaProtocol::TDocument> docs, const TString& grouping, const TString& category) = 0;
    virtual void AddReportProperty(const TString& propName, const TString& propValue) = 0;

    template <class T>
    void AddReportProperty(const TString& propName, const T& propValue) {
        AddReportProperty(propName, ToString(propValue));
    }

    virtual void AddErrorMessage(const TString& msg) = 0;
    virtual void ConsumeReport(NMetaProtocol::TReport& report, const TString& source) = 0;
    virtual void MarkIncomplete(bool value = true) = 0;
    virtual void ScanReport(IScanner& scanner) const = 0;
};
