#pragma once

#include "deferred_replier.h"

#include <saas/rtyserver/config/fwd.h>
#include <saas/util/lqueue.h>

class TIndexerServer;

class TSynchronizedDocumentsQueue: public IMessageProcessor, public TDeferredRepliesProcessor {
private:
    const NRTYServer::TIndexerConfig& IndexerConfig;
    const TString& ServiceName;
    TLQueue<TQueuedDocument> DocumentsQueue;
    bool IsActive;

private:
    class TPuter : public INamedLockManager::ICallback {
    public:
        TPuter(TQueuedDocument document, bool forcePut, TSynchronizedDocumentsQueue& queue);
        virtual void OnLock(INamedLockManager::TNamedLockPtr lock);
    private:
        TQueuedDocument Document;
        bool ForcePut;
        TSynchronizedDocumentsQueue& Queue;
    };

private:
    void Put(TQueuedDocument& document, bool forcePut);

public:
    TSynchronizedDocumentsQueue(TIndexerServer& indexerServer);
    virtual ~TSynchronizedDocumentsQueue();

    // IMessageProcessor
    virtual TString Name() const {
        return "SyncQueue";
    }
    virtual bool Process(IMessage* message);

    TQueuedDocument Get() {
        TQueuedDocument result;
        if (DocumentsQueue.Get(&result))
            return result;
        return nullptr;
    }

    void LockAndPut(TQueuedDocument& document, bool forcePut = false);
    void Stop();

    bool IsEmpty() const {
        return DocumentsQueue.IsEmpty();
    }
};
