package com.ibiz.util.feign;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import feign.Request.HttpMethod;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;

@Component
public class FeignRequestInterceptor implements RequestInterceptor {

	@Resource
	private ObjectMapper objectMapper;

	public FeignRequestInterceptor() {
		System.out.println();
	}

	@SuppressWarnings("deprecation")
    @Override
	public void apply(RequestTemplate template) {
		if (HttpMethod.GET.name().equals(template.method()) && null != template.body()) {
			try {
				JsonNode jsonNode = objectMapper.readTree(template.body());
				template.body(Request.Body.empty());

				Map<String, Collection<String>> queries = new HashMap<String, Collection<String>>();
				if(template.queries() != null)
					queries.putAll(template.queries());
				buildQuery(jsonNode, "", queries);
				template.queries(queries);
			} catch (IOException e) {
				throw new RuntimeException();
			}
		}
	}

	private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
		// 叶子节点
		if (!jsonNode.isContainerNode()) {
			if (jsonNode.isNull()) {
				return;
			}
			Collection<String> values = queries.get(path);
			if (null == values) {
				values = new ArrayList<String>();
				queries.put(path, values);
			}
			values.add(jsonNode.asText());
			return;
		}
		// 数组节点
		if (jsonNode.isArray()) {
			Iterator<JsonNode> it = jsonNode.elements();
			while (it.hasNext()) {
				buildQuery(it.next(), path, queries);
			}
		} else {
			Iterator<Map.Entry<String, JsonNode>> it = jsonNode.fields();
			while (it.hasNext()) {
				Map.Entry<String, JsonNode> entry = it.next();
				if (StringUtils.hasText(path)) {
					buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
				} else { // 根节点
					buildQuery(entry.getValue(), entry.getKey(), queries);
				}
			}
		}
	}


}
