#include "manager.h"

#include "config.h"
#include "trie_search_request.h"

#include <kernel/saas_trie/abstract_trie.h>
#include <kernel/saas_trie/memory_trie.h>

#include <saas/rtyserver/config/config.h>
#include <saas/rtyserver/components/fullarchive/manager.h>
#include <saas/rtyserver/model/index.h>

namespace NRTYServer {
    TTrieIndexManager::TTrieIndexManager(TAtomicSharedPtr<NSaasTrie::ITrieStorage> storage)
        : IIndexComponentManager(TrieComponentName)
        , Storage(std::move(storage))
    {
    }

    bool TTrieIndexManager::DoOpen() {
        return true;
    }

    bool TTrieIndexManager::DoClose() {
        return true;
    }

    ui32 TTrieIndexManager::GetDocumentsCount() const {
        return FullArc->GetDocumentsCount();
    }

    void TTrieIndexManager::InitInteractions(const IIndexManagersStorage& storage) {
        FullArc = storage.GetManager<IIndexComponentManager>(FULL_ARCHIVE_COMPONENT_NAME);
        VERIFY_WITH_LOG(FullArc, "Can not find FULLARC manager");
    }

    ui32 TTrieIndexManager::RemoveDocids(const TVector<ui32>& docIds) {
        if (Storage->IsReadOnly()) {
            return 0;
        }
        return static_cast<ui32>(RemoveValuesFromTrie(*Storage, {docIds.begin(), docIds.end()}));
    }

    ui32 GatherTrieDocuments(NSaasTrie::ITrieStorageIterator* iterator,
                             ISimpleReportBuilder& reportBuilder,
                             const IFAManager& fullArc,
                             const TCgiParameters& cgi,
                             ui32 limit) {
        if (!iterator || iterator->AtEnd()) {
            return 0;
        }
        ui32 foundCount = 0;
        do {
            ui64 docId = iterator->GetValue();
            NMetaProtocol::TDocument document;
            if (fullArc.SearchDocument(static_cast<ui32>(docId), cgi, document)) {
                reportBuilder.AddDocument(document);
                if (++foundCount >= limit) {
                    break;
                }
            }
        } while (iterator->Next());
        return foundCount;
    }

    ERTYSearchResult TTrieIndexManager::DoSearch(const TRTYSearchRequestContext& /*context*/,
                                                 ICustomReportBuilder& /*report*/,
                                                 const IIndexController& /*controller*/) const {
        FAIL_LOG("Should never be called because we have overriden IIndexComponent::SearchCustom");
    }

    ui32 TTrieIndexManager::DoSearch(const TTrieSearchRequest& request,
                                     const IFAManager& fullArc,
                                     const TCgiParameters& parameters,
                                     ISimpleReportBuilder& reportBuilder) const {
        auto iterator = request.CreateIterator(*Storage);
        return GatherTrieDocuments(iterator.Get(), reportBuilder, fullArc, parameters, request.GetMaxDocs());
    }
}
