#pragma once

#include <saas/rtyserver/search/processors/processor.h>
#include <library/cpp/logger/global/global.h>
#include <kernel/groupattrs/docsattrs.h>

class TBordersBuilder: public TRTYFacetBase {
private:
    const TVector<TString>& PropertyNames;
    TVector<std::pair<i64, i64> > Result;
    TVector<bool> IsFirst;
public:

    void FillProperties(TSearcherProps* props) const override {
        for (size_t i = 0; i < PropertyNames.size(); i++) {
            if (!IsFirst[i]) {
                props->Set("rty_min_" + PropertyNames[i], ToString(Result[i].first));
                props->Set("rty_max_" + PropertyNames[i], ToString(Result[i].second));
            }
        }
    }

    TBordersBuilder(const TVector<TString>& props)
        : PropertyNames(props)
    {
        Result.resize(PropertyNames.size(), std::make_pair<i64, i64>(0, 0));
        IsFirst.resize(PropertyNames.size(), true);
    }

    virtual void ProcessDoc(ui32 docId, const NGroupingAttrs::TDocsAttrs& da) override {
        for (size_t i = 0; i < PropertyNames.size(); i++) {
            TCategSeries categs;
            if (da.DocCategs(docId, PropertyNames[i].data(), categs))
                for (const TCateg* cat = categs.Begin(); cat != categs.End(); ++cat) {
                    if (*cat > Result[i].second || IsFirst[i])
                        Result[i].second = *cat;
                    if (*cat < Result[i].first || IsFirst[i])
                        Result[i].first = *cat;
                    IsFirst[i] = false;
                }
        }
    }
};

class TSumsBuilder: public TRTYFacetBase {
private:
    const TVector<TString>& PropertyNames;
    THashMap<TStringBuf, i64> Result;
public:

    void FillProperties(TSearcherProps* props) const override {
        for (THashMap<TStringBuf, i64>::const_iterator i = Result.begin(), e = Result.end(); i != e; ++i) {
            props->Set("rty_sum_" + TString(i->first.data()), ToString(i->second));
        }
    }

    TSumsBuilder(const TVector<TString>& props)
        : PropertyNames(props)
    {
        for (size_t i = 0; i < PropertyNames.size(); i++)
            Result[PropertyNames[i].data()] = 0;
    }

    virtual void ProcessDoc(ui32 docId, const NGroupingAttrs::TDocsAttrs& da) override {
        for (THashMap<TStringBuf, i64>::iterator i = Result.begin(); i != Result.end();++i) {
            TCategSeries categs;
            da.DocCategs(docId, i->first.data(), categs);
            for (const TCateg* cat = categs.Begin(); cat != categs.End(); ++cat)
                i->second += *cat;
        }
    }
};
