package com.tofly.getway.balance;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import com.tofly.common.core.constant.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author tuonbed
 * @date 2020/7/21  16:29
 */
//@Component
@Slf4j
public class ToflyChooseBalancerRule extends AbstractLoadBalancerRule {

    @Autowired
    private ValueOperations<String,String> valueOperations;

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {

    }

    /**
     * 自定义的选择方法
     * @param key
     * @return
     */
    @Override
    public Server choose(Object key) {
        List<Server> servers = this.getLoadBalancer().getReachableServers();
        if (servers.isEmpty()) {
            RoundRobinRule roundRobinRule=new RoundRobinRule();
            return roundRobinRule.choose(key);
        }
        if (servers.size() == 1) {
            return servers.get(0);
        }
        if (key == null) {
            return randomChoose(servers);
        }
        return hashKeyChoose(servers, key);
    }

    /**
     * 返回随机实例
     * @param servers
     * @return
     */
    private Server randomChoose(List<Server> servers) {
        int randomIndex = RandomUtils.nextInt(servers.size());
        return servers.get(randomIndex);
    }

    /**
     * 自定义的根据规则返回实例
     * @param servers
     * @param key
     * @return
     */
    private Server hashKeyChoose(List<Server> servers, Object key) {

        String o = valueOperations.get(key);

        log.info("取得的token:{}，调用的端口为：{}",key,o);
        if(o!=null){
            for(Server server:servers){
                if(server.getPort()==Integer.valueOf(o)){
                    return server;
                }
            }
        }
        return randomChoose(servers);

    }
}
