package com.duiba.tuia.youtui.web.tool;

import cn.com.duiba.tuia.activity.center.api.constant.ParseType;
import cn.com.duiba.wolf.utils.UrlUtils;
import com.alibaba.fastjson.JSONObject;
import com.duiba.tuia.youtui.web.exception.ActivityRuntimeException;
import com.duiba.tuia.youtui.web.model.HttpRequest;
import org.apache.http.HttpMessage;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class HttpRequestTool {

    private static final Logger logger = LoggerFactory.getLogger(HttpRequestTool.class);

    private HttpRequestTool() {
    }

    public static String requestByGet(String url) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault();) {
            HttpGet httpget = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpget);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            logger.error("", e);
        }
        return null;
    }

    public static String requestByPost(String url, Map<String, Object> param) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault();) {
            HttpPost httppost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
            httppost.setConfig(requestConfig);
            httppost.setEntity(new UrlEncodedFormEntity(getPostParam(param), "UTF-8"));

            CloseableHttpResponse response = httpClient.execute(httppost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            logger.error("", e);
            return null;
        }
        return null;
    }

    public static String requestByPost(String url, String request) {
        String resp;
        try (CloseableHttpClient httpClient = HttpClients.createDefault();) {
            HttpPost httppost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
            httppost.setConfig(requestConfig);
            httppost.setEntity(new StringEntity(request, "UTF-8"));
            httppost.setHeader("Content-Type", "application/json");

            CloseableHttpResponse response = httpClient.execute(httppost);
            resp = EntityUtils.toString(response.getEntity());
            response.close();
            httpClient.close();
            return resp;
        } catch (IOException e) {
            logger.error("", e);
            return null;
        }
    }

    public static void request(HttpRequest request) {
        String method = request.getMethod();
        String response = null;
        String url;

        //生成url
        Map<String, String> urlParams = request.getUrlParams();
        if (urlParams == null || urlParams.isEmpty()) {
            url = request.getUrl();
        } else {
            url = UrlUtils.appendParams(request.getUrl(), urlParams);
        }


        //调用获取结果
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            CloseableHttpResponse httpResponse;
            if (HttpPost.METHOD_NAME.equalsIgnoreCase(method)) {
                HttpPost httpPost = new HttpPost(url);
                RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
                httpPost.setConfig(requestConfig);

                if (ParseType.FORM == request.getRequestType()) {
                    httpPost.setEntity(new UrlEncodedFormEntity(getPostParam(request.getBodyParams()), "UTF-8"));
                } else if (ParseType.JSON == request.getRequestType()) {
                    String json = JSONObject.toJSONString(request.getBodyParams());
                    httpPost.setEntity(new StringEntity(json, "UTF-8"));
                }

                setHead(request.getHeadParams(), httpPost);
                httpResponse = httpClient.execute(httpPost);
                request.setRequest(EntityUtils.toString(httpPost.getEntity()));

            } else if (HttpGet.METHOD_NAME.equalsIgnoreCase(method)) {
                HttpGet httpGet = new HttpGet(url);
                setHead(request.getHeadParams(), httpGet);
                httpResponse = httpClient.execute(httpGet);
            } else {
                throw new ActivityRuntimeException("sorry,don't support this method " + method);
            }
            response = EntityUtils.toString(httpResponse.getEntity());
            request.setResponse(response);
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            try {
                if (null != httpClient) {
                    httpClient.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private static void setHead(Map<String, String> headParams, HttpMessage httpMessage) {
        if (headParams != null && !headParams.isEmpty()) {

            Set<String> keys = headParams.keySet();
            for (String key : keys) {
                httpMessage.setHeader(key, headParams.get(key));
            }

        }


    }

    public static List<NameValuePair> getPostParam(Map<String, Object> map) {
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        for (Entry<String, Object> entry : map.entrySet()) {
            if (null != entry.getValue()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
            }
        }
        return nameValuePairs;
    }

    public static List<NameValuePair> getPostParamString(Map<String, String> map) {
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        for (Entry<String, String> entry : map.entrySet()) {
            if (null != entry.getValue()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
            }
        }
        return nameValuePairs;
    }

}
