#pragma once
#include "json.h"

#include <library/cpp/cgiparam/cgiparam.h>


class TYSuggestFormatter : public IJsonFormatterBase {
public:
    TYSuggestFormatter(const TCgiParameters& cgi)
        : IJsonFormatterBase(cgi)
    {
        Result.SetType(NJson::JSON_ARRAY);

        PropName = cgi.Get("ysuggest_report_field", 0);
        TStringBuf asString = cgi.Get("ysuggest_as_string", 0);
        if (asString) {
            AsString = IsTrue(asString);
        }
        TStringBuf responsesOnly = cgi.Get("ysuggest_responses_only", 0);
        if (responsesOnly) {
            ResponsesOnly = IsTrue(responsesOnly);
        }
    }

    virtual void OnRequestPage(const long /*page*/) override {};

    virtual bool OnDocument(const ISearchReplyData::TMainDocArchiveInfo& info) override {
        if (!PropName) {
            AppendDocData(info.Url);
        } else if (PropName == "_Title") {
            AppendDocData(info.Title);
        }
        return true;
    }

    virtual void OnDocAttribute(const TString& name, const TString& value) override {
        if (!PropName || PropName == "_Title")
            return;

        if (name == PropName) {
            AppendDocData(value);
        }
    }

    virtual void OnRequestText(const TString& text) override {
        if (!ResponsesOnly) {
            Result.AppendValue(text);
        }
    }

    virtual bool OnGrouping(const TGroupingIndex&, const ISearchReplyData::TGroupingInfo&, const ISearchReplyData::TPagingInfo&, const int) override { return true; }
    virtual bool OnGroup(const ISearchReplyData::TGroupInfo&) override { return true; }
    virtual void OnCateg(const ISearchReplyData::TDocCategInfo& , const TString& , ui64 ) override {}
    virtual void OnReportStat(const TRelevStatEx&) override {}
    virtual void OnSearchProperties(TSearcherPropsRef) override {}
    virtual void OnError(const TString&) override {}

private:
    void AppendDocData(const TString& data) {
        if (ResponsesOnly) {
            AppendData(data, Result);
        } else {
            if (Result.GetArray().size() == 1)
                AppendData(data, Result.AppendValue(NJson::JSON_ARRAY));
            else {
                AppendData(data, Result.Back());
            }
        }
    }

    void AppendData(const TString& data, NJson::TJsonValue& result) {
        NJson::TJsonValue json;
        if (!AsString && NJson::ReadJsonFastTree(data, &json)) {
            result.AppendValue(json);
        } else {
            result.AppendValue(data);
        }
    }

private:
    bool AsString = true;
    bool ResponsesOnly = false;
    TString PropName;

    static TFactory::TRegistrator<TYSuggestFormatter> Registrator;
};
