#pragma once

#include "position.h"
#include "zones_description_interface.h"
#include "zones_makeup.h"
#include <library/cpp/logger/global/global.h>
#include <util/generic/hash.h>
#include <util/generic/hash_set.h>
#include "makeup_storage_interface.h"
#include <saas/rtyserver/merger/library/block_merger.h>

namespace NZonesMakeup {

    class TDocumentMakeup {
    public:
        TDocumentMakeup(IMakeupStorage* makeupStorage, bool correct);
        TDocumentMakeup(IMakeupStorage* makeupStorage, IInputStream& in, int version, bool deep);
        TDocumentMakeup(IMakeupStorage* makeupStorage, const TDocumentMakeup& doc);
        bool GetIsCorrectDocument() const;
        ui32 GetZoneLengthInWords(const ui32 zoneNumber) const;
        const IMakeupStorage* GetMakeupStorage() const;
        void CleanSpans();
        void Serialize(IOutputStream& out, bool deep) const;
        void Deserialize(IInputStream& in, int version, bool deep);
        void StoreZone(NZonesMakeup::TZoneNumber numZone, ui16 sentBegin, ui16 wordBegin, ui32 wordBeginInDoc, ui16 sentEnd, ui16 wordEnd, ui32 wordEndInDoc);
        void BuildMakeup();
        bool operator == (const TDocumentMakeup& other) const;
        bool operator != (const TDocumentMakeup& other) const;
        inline TZoneId GetSentZones(ui32 sent) const {
            Y_ASSERT(IsCorrectDocument);
            Y_ASSERT(MakeupStorage->GetDoClean());
            return (sent < SentsMakeup.size()) ? SentsMakeup[sent] : 0;
        }
        inline ui32 GetSentCount() const {
            return SentsMakeup.size();
        }

        const TLengthZones& GetZoneLength() const {
            return ZoneLength;
        };

        const TSentsMakeup& GetSentsMakeup() const {
            return SentsMakeup;
        };

    protected:
        TLengthZones ZoneLength;
        IMakeupStorage* MakeupStorage;
        TSentsMakeup SentsMakeup;
        TSpansZones SpansZones;
        bool IsCorrectDocument;
    };

    class TDocumentMergerWriter : public TDocumentMakeup, public NRTYMerger::IObject {
    public:
        TDocumentMergerWriter(IMakeupStorage* makeupStorage, bool correct)
            : TDocumentMakeup(makeupStorage, correct)
        {

        }
        virtual void SerializeForMerger(NRTYMerger::IHeader* from, NRTYMerger::IHeader* to, IOutputStream& os) override;
        virtual void DeserializeForMerger(IInputStream& os) override;
    };
}
