#pragma once

#include "makeup_storage_interface.h"
#include <saas/protos/rtyserver.pb.h>
#include <kernel/keyinv/indexfile/indexstorageface.h>

class TMakeupSaver {
public:
    TMakeupSaver(IMakeupWritableStorageOwner* storage, bool isPrefixed);
    void StorePositionsAttr(const char *key, const SUPERLONG *positions, const size_t posCount);
    void StorePositionsLemm(const char *key, const SUPERLONG *positions, const size_t posCount);
    IYndexStorage* GetAttrIFace();
    IYndexStorage* GetLemmIFace();
    void Reset();
    void Finish(ui32 docid);

    static bool IsZoneForSaving(const char* key, const bool isPrefixed);
    static bool IsKeyInteresting(const char* key);

private:
    struct TInterestPoint {
        NZonesMakeup::TZoneNumber Zone;
        SUPERLONG Position;
        inline TInterestPoint()
            : Zone(Max<NZonesMakeup::TZoneNumber>())
            , Position(Max<SUPERLONG>())
        {}

        inline TInterestPoint(NZonesMakeup::TZoneNumber zone, SUPERLONG position)
            : Zone(zone)
            , Position(position)
        {}

        inline bool operator < (const TInterestPoint& other) const {
            if (Zone < other.Zone)
                return true;
            if (Zone > other.Zone)
                return false;
            return Position < other.Position;
        }
    };
    template<bool IsAttr>
    class TMakeupSaverIFace: public IYndexStorage {
    public:
        TMakeupSaverIFace(TMakeupSaver& parent)
            : Parent(parent)
        {}
        void StorePositions(const char *key, SUPERLONG *positions, size_t posCount) override final {
            if (IsAttr) {
                Parent.StorePositionsAttr(key, positions, posCount);
            } else {
                Parent.StorePositionsLemm(key, positions, posCount);
            }
        }
    private:
        TMakeupSaver& Parent;
    };
    typedef ui32 TSentanceLength;

    typedef TVector<TInterestPoint, TOptionalAllocator> TInterestPosints;
    typedef TVector<TSentanceLength, TOptionalAllocator> TSentLen;
    void SetKps(const char* key);
    void StoreIntersetPoint(const char* key, SUPERLONG position, TInterestPosints& points);
    ui32 GetWordInDoc(ui16 sent, ui16 word) const;
    bool StoreZones(ui32 docid);
    IMakeupWritableStorageOwner* Storage = nullptr;
    bool IsPrefixed = false;
    ui64 Kps = 0;
    TSentLen SentLen;
    TInterestPosints ZoneBegins;
    TInterestPosints ZoneEnds;
    TMakeupSaverIFace<true> IFaceAttr;
    TMakeupSaverIFace<false> IFaceLemm;
};
