#pragma once

#include <saas/protos/rtyserver.pb.h>

#include <kernel/indexer/faceproc/docattrs.h>
#include <kernel/indexer/face/docinfo.h>

#include <library/cpp/logger/global/global.h>

#include <util/string/cast.h>

namespace NRTYServer {
    struct TAttr {
        enum TUpdateAction {
            uaREPLACE,
            uaADD
        };

        TVector<TString> Values;
        TFullDocAttrs::EAttrType Type = TFullDocAttrs::AttrAuxPars;
        TUpdateAction Action = uaREPLACE;
        ui32 Index = 0;

        template <class T>
        static T GetUpdateValue(const T& oldValue, const TString& newValue, TUpdateAction action) {
            switch (action) {
                case uaREPLACE:
                    return FromString<T>(newValue);
                case uaADD:
                    return oldValue + FromString<T>(newValue);
                default:
                    FAIL_LOG("Invalid Usage");
            }
            return T();
        }
    };

    class TAttrs: public THashMap<TString, TAttr> {
    public:
        TAttr& Insert(const TString& name, const TString& data, TFullDocAttrs::EAttrType type, ui32 index = 0, bool detectUtf8 = true);
        void Clear(const TString& name);
        typedef NRTYServer::TAttribute::TAttributeType(TAttrTypeGeter)(const TAttr& attr);
        void Serialize(google::protobuf::RepeatedPtrField<NRTYServer::TAttribute>& field, TAttrTypeGeter* attrTypeGetter) const;
        void Serialize(google::protobuf::RepeatedPtrField<NRTYServer::TMessage::TDocument::TProperty>& field) const;
        void ApplyPatch(const TAttrs& patch);

        static TString ExtractValue(TStringBuf data, TFullDocAttrs::EAttrType type, bool detectUtf8 = true);
    };
}
