/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.http.interceptor;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.Charsets;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.methods.HttpRequestWrapper;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.crunii.micro.common.constants.CommonConstants;
import com.crunii.micro.common.http.HttpClientHolder;
import com.crunii.micro.common.utils.BusiLogUtil;
import com.crunii.micro.common.utils.IPUtil;
import com.crunii.micro.common.utils.JsonUtil;

/**
 * @author 田平 create 2020年1月10日上午11:27:08
 *
 */
public class LogHttpReqInterceptor implements HttpRequestInterceptor {

	/**
	 * @see org.apache.http.HttpRequestInterceptor#process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext)
	 */
	@Override
	public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
		Map<String, Object> busiInfo = HttpClientHolder.busiLogInfo.get();
		busiInfo.putIfAbsent("callTime", new Date());
		busiInfo.put("logType", CommonConstants.TYPE_CLIENT);
		busiInfo.put("clientAddr", IPUtil.getIP());
		HttpRequestWrapper wrapper = (HttpRequestWrapper) request;
		busiInfo.put("serverAddr", getServerAddr(wrapper));
		busiInfo.put("methodInfo", wrapper.getMethod());

		Map<String, Object> sendData = new HashMap<String, Object>();
		sendData.put("uri", wrapper.getURI());
		HttpRequest httpRequest = wrapper.getOriginal();
		sendData.put("headers", HttpClientHolder.getHeaderInfo(httpRequest.getAllHeaders()));
		if (httpRequest instanceof HttpEntityEnclosingRequest) {
			HttpEntityEnclosingRequest base = (HttpEntityEnclosingRequest) httpRequest;
			HttpEntity entity = base.getEntity();
			String body = (String) busiInfo.remove(HttpClientHolder.REQ_BODY_KEY);
			if (ObjectUtils.isEmpty(body)) {
				if (entity != null) {
					String contentType = entity.getContentType() != null ? entity.getContentType().getValue() : null;
					if (BusiLogUtil.checkContentType(contentType) && entity instanceof AbstractHttpEntity) {
						body = EntityUtils.toString(base.getEntity(), Charsets.UTF_8);
						sendData.put("body", body);
					} else {
						sendData.put("body", "can not record body!");
					}
				} else {
					sendData.put("body", body);
				}
			}
		} else {
			sendData.put("body", busiInfo.remove("body"));
		}
		HttpClientHolder.busiLogInfo.get().put("sendData", JsonUtil.getJsonString(sendData));
	}

	private static String getServerAddr(HttpRequestWrapper wrapper) {
		String addr = null;
		if (wrapper != null) {
			if (wrapper.getTarget() != null) {
				addr = wrapper.getTarget().toString();
			}
			if (wrapper.getURI() != null) {
				addr = addr + wrapper.getURI().getPath();
			}
		}
		return addr;
	}

	public static void main(String[] args) {
		System.out.println(URLEncodedUtils.parse("username=%E5%B0%8F%E6%98%8E&password=abc123", Charsets.UTF_8));
	}

}
