#include "ddk_config.h"
#include "ddk_builder.h"
#include "ddk_manager.h"
#include "ddk_parsed_entity.h"
#include "metrics.h"

#include <saas/rtyserver/config/const.h>
#include <saas/rtyserver/components/erf/erf_builder.h>
#include <saas/rtyserver/unistat_signals/signals.h>

TRTYDDKBuilder::TRTYDDKBuilder(TRTYErfBuilder* base, const TDDKComponentConfig& config, TDDKMetrics& metrics, const TString& componentName)
    : NRTYServer::IIndexComponentBuilder(componentName)
    , Base(base)
    , DocCount(0)
    , DocSize(0)
    , Config(config)
    , Merger(false)
    , Metrics(metrics)
{
    Y_ASSERT(Base);
    TAutoPtr<IRTYErfManager> baseManager(Base->GetErfManager());
    Y_ASSERT(baseManager);
    Manager = new TRTYDDKManager(baseManager, Config);
}

TRTYDDKBuilder::TRTYDDKBuilder(THolder<TRTYErfBuilder> base, const TDDKComponentConfig& config, TDDKMetrics& metrics, const TString& componentName)
    : TRTYDDKBuilder(base.Get(), config, metrics, componentName)
{
    BaseHolder.Reset(base);
}

TRTYDDKBuilder::~TRTYDDKBuilder() {
}

NRTYServer::IIndexComponentManager* TRTYDDKBuilder::GetManager() {
    return Manager;
}

void TRTYDDKBuilder::Index(int threadID, const TParsedDocument& document, const ui32 docId) {
    auto entity = document.GetComponentEntity<TRTYDDKParsedEntity>(DDK_COMPONENT_NAME);
    VERIFY_WITH_LOG(entity, "Cannot find DDK parsed entity");

    AtomicIncrement(DocCount);
    AtomicAdd(DocSize, entity->GetSize());

    Y_ASSERT(Base);
    Base->Index(threadID, document, docId);
}

bool TRTYDDKBuilder::DoClose(const NRTYServer::TBuilderCloseContext& context) {
    if (!Merger && DocCount) {
        const ui32 value = DocSize / DocCount;
        Metrics.DocumentSize.Set(value);
        TSaasRTYServerSignals::UpdateAverageDocSize(value);
    }

    Y_ASSERT(Base);
    return Base->Close(context);
}

bool TRTYDDKBuilder::Start() {
    Y_ASSERT(Base);
    return Base->Start();
}

bool TRTYDDKBuilder::Stop() {
    Y_ASSERT(Base);
    return Base->Stop();
}

void TRTYDDKBuilder::InitInteractions(const NRTYServer::IIndexBuildersStorage& storage) {
    Y_ASSERT(Base);
    return Base->InitInteractions(storage);
}
