#pragma once

#include <search/lingboost/hits_streamizer/rt_hits.h>
#include <search/lingboost/limits/limits_config.h>
#include <search/lingboost/relev/features_calcer.h>

#include <kernel/factor_storage/factor_view.h>
#include <kernel/indexann/interface/reader.h>
#include <kernel/text_machine/interface/text_machine.h>
#include <kernel/sent_lens/sent_lens.h>

#include <library/cpp/object_factory/object_factory.h>

class ISaasTextMachinePlugin: public TThrRefBase {
public:
    virtual bool IsExternalRelevanceCalcer() const {
        // if true, the machine is applied through ExternalRelevanceCalcFactorsHelper (this means, by Basesearch)
        // if false, SaaS handles everything
        return false;
    }

    virtual NFactorSlices::EFactorSlice GetTargetSlice() const = 0;

    const NLingBoost::TWordConfig* GetWordConfig() const;

    const NLingBoost::TRawConfig* GetRawConfig() const;

    virtual THolder<NLingBoost::IProductionFeaturesCalcer> CreateProductionCalcer(const NTextMachine::TExpansionOptions&) const = 0;

    virtual THolder<NLingBoost::IExperimentFeaturesCalcer> CreateExperimentCalcer(const NTextMachine::TExpansionOptions&) const {
        return nullptr;
    };

    virtual THolder<NLingBoost::IHitsStreamizer> CreateAnnHitsStreamizer(
        TCateg relevCountry,
        const NIndexAnn::IDocDataIndex* annIndex,
        const TSentenceLengthsReader* annSentReader) const {
        return NLingBoost::CreateAnnHitsStreamizer(relevCountry, annIndex, annSentReader);
    }

    virtual THolder<NLingBoost::IHitsStreamizer> CreateFactorAnnHitsStreamizer(
        TCateg relevCountry,
        const NIndexAnn::IDocDataIndex* factorAnnIndex,
        const TSentenceLengthsReader* factorAnnSentLenReader) const {
        return NLingBoost::CreateFactorAnnHitsStreamizer(relevCountry, factorAnnSentLenReader, factorAnnIndex);
    }

protected:
    THolder<NLingBoost::TWordConfig> DefaultWordConfig;
    THolder<NLingBoost::TRawConfig> DefaultRawConfig;

public:
    using TFactory = NObjectFactory::TObjectFactory<ISaasTextMachinePlugin, TString>;
};

namespace NRTYServer {
    // TSaasTextMachine: use the default web calcer
    class TSaasTextMachine: public ISaasTextMachinePlugin {
    public:
        bool IsExternalRelevanceCalcer() const override {
            return true; // legacy mode
        }

        NFactorSlices::EFactorSlice GetTargetSlice() const override;

        THolder<NLingBoost::IProductionFeaturesCalcer> CreateProductionCalcer(const NTextMachine::TExpansionOptions&) const override;

    private:
        static TFactory::TRegistrator<TSaasTextMachine> Registrator;
    };

    // TSaasTextMachine2: use the default web calcer, but explicitly
    class TSaasTextMachine2: public TSaasTextMachine {
    public:
        bool IsExternalRelevanceCalcer() const override {
            // TODO(SAAS-5877): сделать этот false безальтернативным (т.е. всегда вызывать текстовую машину из СааСа, а не из базового)
            return false;
        }

    private:
        static TFactory::TRegistrator<TSaasTextMachine2> Registrator;
    };

    class TMusicTextMachine: public ISaasTextMachinePlugin {
    public:
        NFactorSlices::EFactorSlice GetTargetSlice() const override;

        THolder<NLingBoost::IProductionFeaturesCalcer> CreateProductionCalcer(const NTextMachine::TExpansionOptions&) const override;

        THolder<NLingBoost::IHitsStreamizer> CreateAnnHitsStreamizer(
            TCateg relevCountry, 
            const NIndexAnn::IDocDataIndex* annIndex, 
            const TSentenceLengthsReader* annSentReader
        ) const override;

        THolder<NLingBoost::IHitsStreamizer> CreateFactorAnnHitsStreamizer(
            TCateg relevCountry, 
            const NIndexAnn::IDocDataIndex* factorAnnIndex,
            const TSentenceLengthsReader* factorAnnSentLenReader
        ) const override;

    private:
        static TFactory::TRegistrator<TMusicTextMachine> Registrator;
    };

    class TKinopoiskTextMachine: public ISaasTextMachinePlugin {
    public:
        NFactorSlices::EFactorSlice GetTargetSlice() const override;

        THolder<NLingBoost::IProductionFeaturesCalcer> CreateProductionCalcer(const NTextMachine::TExpansionOptions&) const override;
    private:
        static TFactory::TRegistrator<TKinopoiskTextMachine> Registrator;
    };
}
