package com.sf.vertx.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import com.sf.vertx.api.pojo.AppConfig;
import com.sf.vertx.api.pojo.Node;
import com.sf.vertx.api.pojo.RouteContent;
import com.sf.vertx.api.pojo.SacService;
import com.sf.vertx.arithmetic.roundRobin.SacLoadBalancing;
import com.sf.vertx.arithmetic.roundRobin.WeightedRoundRobin;
import com.sf.vertx.service.impl.AppConfigServiceImpl;

import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.net.SocketAddress;
import io.vertx.ext.web.handler.HttpException;
import lombok.extern.slf4j.Slf4j;

/***
 * 反向代理工具类
 * 
 * @author xy
 *
 */
@Slf4j
public class ProxyTool {
	public final static Map<Integer, String> _ERROR = new HashMap<>();
	public static final String DEFAULT_ERROR_MSG = "{\n" + "    \"msg\": \"服务请求失败,请稍后再试\",\n" + "    \"code\": 501,\n" + "    \"data\": \"服务请求失败,请稍后再试\"\n" + "}";
	static {
		_ERROR.put(400, "Bad Request");
		_ERROR.put(401, "Unauthorized");
		_ERROR.put(403, "Forbidden");
		_ERROR.put(404, "Not Found");
		_ERROR.put(413, "Request Entity Too Large");
		_ERROR.put(415, "Unsupported Media Type");
		_ERROR.put(500, "Internal Server Error");
		_ERROR.put(502, "Bad Gateway");
		_ERROR.put(503, "Service Unavailable");
		_ERROR.put(504, "Gateway Timeout");
		_ERROR.put(504, "Gateway Timeout");
		
		_ERROR.put(10000, "无法找到路由地址");
		_ERROR.put(10001, "加解密算法传递错误");
		_ERROR.put(10003, "参数传递错误");
		
		_ERROR.put(10101, "接口限流错误");
		_ERROR.put(10102, "应用限流错误");
		
		_ERROR.put(10103, "{\n" + "    \"msg\": \"接口连接失败\",\n" + "    \"code\": 10103,\n" + "    \"data\": \"接口连接失败\"\n" + "}"); // 接口连接失败
		_ERROR.put(10104, "{\n" + "    \"msg\": \"应用连接失败\",\n" + "    \"code\": 10103,\n" + "    \"data\": \"应用连接失败\"\n" + "}"); // 应用连接失败
	};

	public static SocketAddress resolveOriginAddress(HttpServerRequest request) {
		String appCode = request.getHeader(AppConfigServiceImpl.getSacAppHeaderKey());
		String appHeaderServiceName = request.getHeader(AppConfigServiceImpl.getAppHeaderServiceName());
		log.info("uri:{}, header appCode:{},appHeaderServiceName:{}", request.uri(), appCode, appHeaderServiceName);
		
		SacLoadBalancing sacLoadBalancing = AppConfigServiceImpl.getSacLoadBalancing(appCode, appHeaderServiceName);
		// TODO 区分https、http
		Node node = sacLoadBalancing.selectNode();
		SocketAddress socketAddress = SocketAddress.inetSocketAddress(node.getPort(), node.getIp());
		log.info("sacLoadBalancing address:{},port:{}", socketAddress.host(), socketAddress.port());
		return socketAddress;
	}

	public static boolean regexMatch(String pattern, String target) {
		return Pattern.matches(pattern, target);
	}

	public static SacLoadBalancing roundRobin(List<Node> nodeList) {
		WeightedRoundRobin weightedRoundRobin = new WeightedRoundRobin();
		for (Node node : nodeList) {
			int weight = node.getWeight() != null ? node.getWeight() : 1;
			node.setWeight(weight);
			node.setCurrentWeight(weight);
			node.setEffectiveWeight(weight);
			weightedRoundRobin.totalWeight += node.getEffectiveWeight();
		}
		weightedRoundRobin.init(nodeList);
		return weightedRoundRobin;
	}
}
