#include "rty_features.h"

#include <saas/rtyserver/search/cgi/rty_external_cgi.h>
#include <util/generic/vector.h>

using namespace NRTYFactors;

namespace NRTYFeatures {
//
// TRTYFactorsCalcer
//
class TRTYFactorsCalcer: public IFeatureCalcer {
private:
    const TDynMapping Factors;
    TVector<IFeatureCalcer::TPtr> Calcers;

public:
    TRTYFactorsCalcer(const TVector<IFeature::TPtr>& features, const TDynMapping& factorsInRequest, const NRTYFactors::TConfig* relevCfg, bool fastFeaturesOnly)
        : Factors(factorsInRequest)
    {
        Y_ASSERT(relevCfg);

        for (const auto& feature : features) {
            auto calcer = feature->CreateCalcer(Factors, relevCfg, fastFeaturesOnly);
            if (!calcer) {
                continue;
            }
            Calcers.emplace_back(std::move(calcer));
        }
    }

    void Calc(TFactorStorage& storage, const TRTYDynamicFeatureContext& ctx, ui32 docId) override {
        // zero all factors before calculus
        for (const auto& factor : Factors) {
            if (factor.BaseIndex >= 0) {
                storage[factor.BaseIndex] = 0.0f;
            }
        }
        for (const IFeatureCalcer::TPtr& calcer : Calcers) {
            calcer->Calc(storage, ctx, docId);
        }
    }
};

void InitModels(const TDynMapping& factorsInConfig, const NRTYFactors::TConfig* relevCfg, const TString& modelsPath) {
    for (const auto& f : relevCfg->GetRTYFeatures()) {
        f->InitModels(factorsInConfig, relevCfg, modelsPath);
    }
}

TIntrusivePtr<IFeatureCalcer> CreateCalcer(const TDynMapping& factorsInRequest, const NRTYFactors::TConfig* relevCfg, bool fastFeaturesOnly) {
    return MakeIntrusive<TRTYFactorsCalcer>(relevCfg->GetRTYFeatures(), factorsInRequest, relevCfg, fastFeaturesOnly);
}

} // namespace NRTYFeatures
