#pragma once

#include <util/generic/map.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>

#include <array>

class TCgiParameters;
class TSearchRequestData;

namespace NSc {
    class TValue;
}

namespace NSaas {

namespace NExperiments {

enum EType { TDI, ABT, ABTIOT, UNDEF };

struct TBucket {
    i64 Id;
    i64 Slot;
    i64 Bucket;
};
using TBuckets = TVector<TBucket>;

struct TSourceParam {
    TString Source;
    TString Name;
    TString Value;
};
using TSourceParams = TVector<TSourceParam>;

struct TExperimentParams: public std::array<TSourceParams, 2> {
    EType Type = UNDEF;
    TVector<TString> Attributes;
};
using TExperiments = TMap<ui64, TExperimentParams>;

struct TUserCtx {
    ui64 ConfigVersion = 0;
    TExperiments Experiments;
    TBuckets Buckets;

public:
    void Fill(const TCgiParameters& cgi, const TSearchRequestData& rd);

    inline bool HasExperiment() const {
        Y_ASSERT(Experiments.empty() == Buckets.empty());
        return !Experiments.empty();
    }

private:
    void FillParamsFromScheme(const NSc::TValue& scheme, ui64 id);
    void FillParamsFromScheme(const NSc::TValue& scheme, TSourceParams& params);
    bool IsEligibleClient(const NSc::TValue& scheme);
};

static const size_t A = 0;
static const size_t B = 1;

}
}
