#include "active.h"

#include <balancer/kernel/balancer/algorithm.h>
#include <balancer/kernel/balancing/backend.h>
#include <balancer/modules/balancer/policies/policy_factory.h>

namespace NSrvKernel::NActive {

IBackend* TActivePolicy::Next(IAlgorithm* algo, bool fastAttempt) noexcept {
    do {
        IBackend* next = Slave_->Next(algo, fastAttempt);
        if (next == nullptr || next->Enabled()) {
            return next;
        }
    } while (SkipAttempts_--);

    return nullptr;
}


POLICY_FACTORY_BASE(active_policy, TPolicyFactoryWithSlave), public TModuleParams {
    TPolicyFactory(const TModuleParams& mp)
        : TModuleParams(mp)
    {
        Config->ForEach(this);
        CheckConfiguration();
    }

    THolder<IPolicy> ConstructPolicy(const TStepParams& params) noexcept override {
        return MakeHolder<TActivePolicy>(TPolicyBase::ConstructPolicy(params), SkipAttempts_);
    }

private:
    START_PARSE {
        ON_KEY("skip_attempts", SkipAttempts_) {
            return;
        }

        if (Configure(key, Copy(value->AsSubConfig()))) {
            return;
        }
    } END_PARSE

private:
    size_t SkipAttempts_ = std::numeric_limits<size_t>::max();
};

INodeHandle<IPolicyFactory>* Handle() {
    return TPolicyFactory::Handle();
}

}  // namespace NSrvKernel::NActive
