#pragma once

#include <search/reqparam/reqparam.h>
#include <saas/rtyserver/config/fwd.h>
#include <saas/rtyserver/config/searcher_config.h>
#include <ysite/yandex/posfilter/filtration_model.h>

class TRTYFiltrationWeightedModel: public IFiltrationModel {
private:
    bool IsStrict;
public:
    TRTYFiltrationWeightedModel(const TQueryFiltrationInfo& queryInfo)
        : IsStrict(queryInfo.GetNumNonStopWords() <= 1)
    {
    }

    virtual float GetTextWeight(const TSkobkaInfo& info, size_t /*index*/, bool /*useIahc*/) const {
        if (info.DocFreq)
            return 1/info.DocFreq;
        else
            return Max<float>();
    }
    virtual float GetQuorumWeight(const TSkobkaInfo& info, size_t i) const {
        return GetTextWeight(info, i, true);
    }

    virtual bool IsStrictFiltrationEnabled() const {
        return IsStrict;
    }

    virtual TString GetCaption() const {
        return "RTY_FILTRATION_WEIGHTED_MODEL";
    }
};

class TRTYFiltrationSimpleModel: public TRTYFiltrationWeightedModel {
public:
    TRTYFiltrationSimpleModel(const TQueryFiltrationInfo& queryInfo)
        : TRTYFiltrationWeightedModel(queryInfo)
    {
    }

    virtual float GetTextWeight(const TSkobkaInfo& /*info*/, size_t /*index*/, bool /*useIahc*/) const {
        return 1;
    }

    virtual TString GetCaption() const {
        return "RTY_FILTRATION_SIMPLE_MODEL";
    }
};

class TSoftnessModelSimple: public ISoftnessModel {
public:
    virtual float CalcSoftnessQuorum(ui32 softness, ui32 /*wordCount*/) const {
        return 1 - softness / 100.0f;
    }
};

class TRTYFiltrationModelFactory : public IFiltrationModelFactory {
public:
    TRTYFiltrationModelFactory() {
    }
    virtual TAutoPtr<IFiltrationModel> CreateFiltrationModel(int filtrationType, const TQueryFiltrationInfo& queryInfo) const {
        if (filtrationType == NRTYServer::TSearcherConfig::fmSimple) {
            return new TRTYFiltrationSimpleModel(queryInfo);
        } else if (filtrationType == NRTYServer::TSearcherConfig::fmWeight) {
            return new TRTYFiltrationWeightedModel(queryInfo);
        }
        Y_ASSERT(0);
        return nullptr;
    }
    virtual const ISoftnessModel& GetSoftnessModel() const {
        return SoftnessModelSimple;
    }
private:
    TSoftnessModelSimple SoftnessModelSimple;
};
