#pragma once

#include <saas/rtyserver/indexer_core/parsed_document.h>

#include <kernel/multipart_archive/multipart.h>

class TRTYFullArchiveConfig;

class TRTYFullArchiveLayer {
protected:
    using TLayerConfig = NRTYArchive::TMultipartConfig;

public:
    TRTYFullArchiveLayer(const TRTYServerConfig& config, const TLayerConfig& lConf, const TString& directory, const TString& name, ui32 writeSpeedBytes, bool readOnly);

    virtual ~TRTYFullArchiveLayer() = default;

    void Index(const NRTYServer::TParsedDoc& document, const ui32 docId);

    virtual void Index(const TParsedDocument& document, const ui32 docId) = 0;
    virtual void Index(const TBlob& document, const ui32 docId) = 0;

    bool IsOpen() const;
    void DeserializeParsedDoc(NRTYServer::TParsedDoc& pd, TBlob doc) const;
    TParsedDocument::TPtr DeserializeParsedDocument(const NRTYServer::TParsedDoc& pd, NRTYServer::TMessage::TMessageType command) const;
    virtual bool ReadParsedDoc(NRTYServer::TParsedDoc& pd, ui32 docId, ui32* size) const;
    TBlob ReadRawDoc(ui32 docId) const;
    void RepairByData(const NRTYArchive::TMultipartConfig& config);
    void Open(ui32 docCount);
    void Close();
    bool RemoveDocument(ui32 docid);
    void Remap(const TVector<ui32>& remapTable);
    ui64 GetLockedMemorySize() const;

    inline const TArchiveOwner::TPtr GetArchive() const {
        return Archive;
    }

    static bool CheckLayerRight(const TString& dir, const TString& layerName, const NRTYArchive::TMultipartConfig&);
    static bool Merge(const TString& layerName, const TRTYFullArchiveConfig& componentConfig, const NRTYServer::TMergeContext& context);
    static TFsPath GetArchiveName(const TString& layer);

    using TPtr = TAtomicSharedPtr<TRTYFullArchiveLayer>;

protected:
    NRTYServer::TDocSerializeContext SerializeContext;
    NRTYServer::TDocParseContext ParseContext;
    TArchiveOwner::TPtr Archive;
    const TRTYServerConfig& Config;
    const NRTYArchive::TMultipartConfig& LayerConf;
    TString Directory;
    TString Name;
    bool ReadOnly;
};

class TFAKVLayer final : public TRTYFullArchiveLayer {
public:
    TFAKVLayer(const TRTYServerConfig& config, const TLayerConfig& lc, const TString& directory, const TString& name, ui32 writeSpeedBytes, bool readOnly)
        : TRTYFullArchiveLayer(config, lc, directory, name, writeSpeedBytes, readOnly)
    {
    }

    using TRTYFullArchiveLayer::Index;
    virtual void Index(const TBlob& document, const ui32 docId) override;
    virtual void Index(const TParsedDocument& document, const ui32 docId) override;
};

class TFALightLayer final : public TRTYFullArchiveLayer {
public:
    TFALightLayer(const TRTYServerConfig& config, const TLayerConfig& lc, const TString& directory, const TString& name, ui32 writeSpeedBytes, bool readOnly)
        : TRTYFullArchiveLayer(config, lc, directory, name, writeSpeedBytes, readOnly)
    {
    }

    using TRTYFullArchiveLayer::Index;
    void Index(const TBlob& document, const ui32 docId) override;
    void Index(const TParsedDocument& document, const ui32 docId) override;

    void IndexUnsafe(const TBlob& document, const ui32 docId);

    bool ReadParsedDoc(NRTYServer::TParsedDoc&, ui32, ui32*) const override {
        return false;
    }
};
