#pragma once

#include <library/cpp/json/json_value.h>

#include <util/generic/string.h>
#include <util/generic/vector.h>
#include <util/generic/ptr.h>

namespace NPrivate {

    class TPlainer : public TNonCopyable {
    public:
        class IInserter {
        public:
            virtual ~IInserter() {}
            virtual NJson::TJsonValue*  Insert(const NJson::TJsonValue& source) = 0;
        };

        class IRicher : public TRefCounted < IRicher, TSimpleCounter > {
        public:
            typedef TIntrusivePtr<IRicher> TPtr;
            virtual ~IRicher() {}
            virtual void Rich(NJson::TJsonValue& inserted) = 0;
        };

    public:
        TPlainer(IInserter* inserter, const TString& categories);

        void Process(const NJson::TJsonValue& source, ui32 currentCategory = 0);

        void AddPredInsertRicher(IRicher::TPtr richer);
        void AddPostInsertRicher(IRicher::TPtr richer);

    private:
        struct TCategory {
            TCategory(const TString& str);

            TString Name;
            TStringBuf Value;
            bool NeedValue;
        };
        TVector<TCategory> Categories;
        THolder<IInserter> Inserter;
        TVector<IRicher::TPtr> PredInsertRichers;
        TVector<IRicher::TPtr> PostInsertRichers;
    };

    TString JsonToString(const NJson::TJsonValue& json);
    NJson::TJsonValue StringToJson(const TString& s);
}
