#pragma once

#include "factor.h"

#include <kernel/factor_slices/factor_domain.h>
#include <util/generic/maybe.h>
#include <util/generic/set.h>

namespace NRTYFactors {
    using NFactorSlices::EFactorSlice;
    using NFactorSlices::TFactorIndex;

    class TBaseDomain {
    private:
        struct TAbsoluteIndex {
            TFactorIndex BaseIdx; // Absolute offset in TFactorStorage (not relative to slice)
            EFactorSlice SliceId;
        };

        using TLookup = THashMultiMap<TString, TAbsoluteIndex>;

        using TTraits = TSet<std::pair<TFactorIndex, ui32>>;

    private:
        NFactorSlices::TFactorDomain FactorsDomain_;
        TLookup Lookup_;
        TTraits Traits_;

    public:
        TBaseDomain(const TSet<NFactorSlices::EFactorSlice>& sliceIds, NFactorSlices::EFactorUniverse universe);

        void SetTrait(EFactorSlice slice, TFactorIndex factorId, ui32 category);

        void GetTrait(TSet<ui32>& result, TIndexWebBase baseIdx) const;

        TIndexWebBase GetBaseIdx(const TString& factorName, TMaybe<EFactorSlice> preferredSlice) const;

        TIndexWebBase GetBaseIdx(const ui32 webProductionFactorId) const;

        TMaybe<TFactorIndex> GetWebProductionFactorId(TIndexWebBase baseIdx) const;

        const NFactorSlices::TFactorDomain& GetDomain() const {
            return FactorsDomain_;
        }

    private:
        Y_FORCE_INLINE static i32 GetLookupPriority(EFactorSlice slice, TMaybe<EFactorSlice> preferredSlice);

        static TString FormatNonUnique(TLookup::const_iterator begin, TLookup::const_iterator end);
    };
}
