#pragma once

#include <util/system/types.h>
#include <util/generic/string.h>

class TBasicFactorStorage;
class TBitsRemapper;
class TFactorView;

class TParsedDocument;
namespace NRTYFactors {
    struct TSimpleFactorDescription;
}


class IRTYStaticFactors {
public:
    virtual ~IRTYStaticFactors() {};

    virtual ui32 GetStaticFactorsCount() const = 0;
    virtual const NRTYFactors::TSimpleFactorDescription& GetFactor(ui32 index) const = 0;

    ui32 GetSumWidthBits() const;
    ui32 GetSumWidthBytes() const;
    ui32 GetOffsetInBits(ui32 index) const;
    ui32 GetOffsetInBytes(ui32 index) const;

    TString GetHash() const;
    bool CheckFactorName(const TStringBuf& name, ui32& index) const;

    virtual bool CheckFactorValue(ui32 index, float value) const;

    /// @brief LoadErfBlock copies factors from TParsedDocument to an ERF block.
    ///        The resuling layout is NOT the relev.conf layout.
    /// @seealso TPruningConfig::IDocument::FillFactorStorage
    virtual bool LoadErfBlock(TBasicFactorStorage& data, const TParsedDocument& document) const;
};


class TErfBitsRemapper {
private:
    THolder<TBitsRemapper> SimpleRemapper;
    THolder<TBitsRemapper> FormulaRemapper;
public:

    void PackSimple(const TBasicFactorStorage& data, ui8* storage) const;
    void UnpackSimple(TBasicFactorStorage& data, const ui8* storage) const;
    void UnpackSimple(TFactorView& data, const ui8* storage) const;
    void UnpackFormula(TBasicFactorStorage& data, const ui8* storage) const;
    void UnpackFormula(TFactorView& data, const ui8* storage) const;

    TErfBitsRemapper(const IRTYStaticFactors& info);
};
