#include "cs_manager.h"
#include "cs_parsed_entity.h"
#include "cs_component.h"

bool TCSManager::DoOpen() {
    for (ui32 i = 0; i < NamedBlockErfs.size(); ++i) {
        NamedBlockErfs[i]->Open();
    }
    return true;
}

bool TCSManager::DoClose() {
    bool result = true;
    for (ui32 i = 0; i < NamedBlockErfs.size(); ++i) {
        result &= NamedBlockErfs[i]->Close(RemapTable);
    }
    return result;
}

bool TCSManager::SetRemapTable(const TVector<ui32>* remapTable) {
    RemapTable = remapTable;
    return true;
}

ui32 TCSManager::GetDocumentsCount() const {
    ui32 docsCount = 0;
    for (ui32 i = 0; i < NamedBlockErfs.size(); ++i) {
        if (!i)
            docsCount = NamedBlockErfs[i]->GetDocsCount();
        else if (docsCount != NamedBlockErfs[i]->GetDocsCount()) {
            FAIL_LOG("Incorrect CS manager data");
        }
    }
    return docsCount;
}

void TCSManager::InitInteractions(const NRTYServer::IIndexManagersStorage& /* storage */) {

}

bool TCSManager::GetDocInfo(const ui32 docId, NJson::TJsonValue& result) const {
    bool success = false;
    for (ui32 i = 0; i < NamedBlockErfs.size(); ++i) {
        TNamedBlocksErf::TPtr erf = NamedBlockErfs[i];
        const NRTYFactors::TCSFactorsList::TPtr csFactorsInfo = FactorsInfo[i];
        if (!csFactorsInfo || !erf)
            continue;

        const TString& name = csFactorsInfo->GetFunctionName();
        NJson::TJsonValue block;
        if (erf->GetErfDocInfo(csFactorsInfo->GetFactorsInfo(), docId, block)) {
            result.InsertValue(name, block);
            success = true;
        }
    }
    return success;
}

void TCSManager::Add(const TParsedDocument& document, const ui32 docId, bool replace) {
    const TCSParsedEntity* csEntity = document.GetComponentEntity<TCSParsedEntity>(CS_COMPONENT_NAME);
    if (!csEntity)
        return;
    const THashMap<TString, TDocumentCSInfo>& docInfos = csEntity->GetDocInfos();
    for (THashMap<TString, TDocumentCSInfo>::const_iterator i = docInfos.begin(), e = docInfos.end(); i != e; ++i) {
        bool keyFind = false;
        for (ui32 f = 0; f < NamedBlockErfs.size(); ++f) {
            if (FactorsInfo[f]->GetFunctionName() == i->first) {
                NamedBlockErfs[f]->Add(i->second.GetFValue(), docId, i->second.GetValues(), replace);
                keyFind = true;
                break;
            }
        }
        VERIFY_WITH_LOG(keyFind, "TCSManager::Add failed");
    }
}

bool TCSManager::UpdateDoc(ui32 docId, const TParsedDocument::TPtr doc) {
    Add(*doc, docId, true);
    return true;
}

void TCSManager::CalcFactors(TCalcFactorsContext& ctx, const NRTYFactors::TRTYFactorMask* rtyFactorMask) const
{
    TFactorView factors(static_cast<TBasicFactorStorage&>(*ctx.Factors)); // the 'factors' view here uses layout from relev.conf
    for (ui32 i = 0; i < NamedBlockErfs.size(); ++i) {
        if (!rtyFactorMask->CSFactorsInfo.IsUsed(i)) {
            ERROR_LOG << "Incorrect docid " << ctx.DocId << Endl;
            Y_ASSERT(0);
            continue;
        }
        if (!NamedBlockErfs[i]->Read(factors, ctx.DocId)) {
            ERROR_LOG << "Incorrect docid " << ctx.DocId << Endl;
            Y_ASSERT(0);
        }
    }
}


