package com.house365.web.util;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.house365.beans.entity.WxUserEntity;
import com.house365.rest.exception.ServiceException;
import com.house365.rest.parameter.House365RestResponse;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
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.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpUtil {
    private static final Logger LOG = LoggerFactory.getLogger("HttpUtil");
    private static final String DEFAULT_ENCODING = "UTF-8";

    /**
     *新:get请求
     * @param url
     * @param timeOut
     * @param charSet
     * @return
     * @throws IOException
     */
    public static String getHttpRequest(String url, Map<String, String> map , int timeOut, String charSet) throws IOException {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        long beginTime = System.currentTimeMillis();
        try {
            HttpGet httpGet = new HttpGet();
            URIBuilder builder = new URIBuilder(url);
            httpGet.setURI(builder.build());
            if(StringUtils.isNotBlank(map.get("version"))){
                httpGet.addHeader("version", "v3.0");
            }
            if(StringUtils.isNotBlank(map.get("access-token"))){
                httpGet.addHeader("access-token", map.get("access-token"));
            }
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();//设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();

            String body = null;
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK && httpEntity != null) {
                if (StringUtils.isNotBlank(charSet)) {
                    body = EntityUtils.toString(httpEntity, charSet);
                } else {
                    body = EntityUtils.toString(httpEntity, DEFAULT_ENCODING);
                }
                EntityUtils.consume(httpEntity);
            }
            if (LOG.isInfoEnabled()) {
                logUrlInfo(beginTime, url);
            }
            return body;
        } catch (Exception e) {
            LOG.error(e.toString(), e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    LOG.error(e.toString(), e);
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    LOG.error(e.toString(), e);
                }
            }
        }
        return null;
    }

    public static String doPostWithHeader(String url, List<NameValuePair> params, String access_token, String charSet) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        long beginTime = System.currentTimeMillis();
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            httpPost.addHeader("version", "v3.0");
            httpPost.addHeader("access-token", access_token);

            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            LOG.info("*****StatusCode*******"+httpResponse.getStatusLine().getStatusCode());
            String body = null;
            if (httpEntity != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK ) {
                if (org.apache.commons.lang3.StringUtils.isNotBlank(charSet)) {
                    body = EntityUtils.toString(httpEntity, charSet);
                } else {
                    body = EntityUtils.toString(httpEntity, DEFAULT_ENCODING);
                }
                EntityUtils.consume(httpEntity);
            }

            logUrlInfo(beginTime, url);

            return body;
        } catch (Exception e) {
            LOG.error(e.toString(), e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    LOG.error(e.toString(), e);
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    LOG.error(e.toString(), e);
                }
            }
        }
        return null;
    }

    private static void logUrlInfo(long beginTime, String url) {
        if (System.currentTimeMillis() - beginTime > 1000) {
            LOG.info("call url [{}] , use [{}] ms", url, System.currentTimeMillis() - beginTime);
        }
    }

    /**
     * 生成signature
     * @return
     */
    public static String getSignature(String deciceId, String randStr, String timestamp){
        //获取signature
        List<NameValuePair> signatureInParam = new ArrayList<>();
        signatureInParam.add(new BasicNameValuePair("app_id", "12558119"));
        signatureInParam.add(new BasicNameValuePair("app_secret", "OHuJNOfHSMixNeoedRwScEmzcDAuxnJw"));
        signatureInParam.add(new BasicNameValuePair("device_id", deciceId));
        signatureInParam.add(new BasicNameValuePair("rand_str", randStr));
        signatureInParam.add(new BasicNameValuePair("timestamp", timestamp));
        List<String> newParams = new ArrayList<>();
        for (NameValuePair pair : signatureInParam) {
            newParams.add(pair.getName() + "=" + pair.getValue());
        }
        String newStr = Joiner.on("&").join(newParams);
        String signature = MD5Util.MD5(newStr);
        return signature;
    }

    public static String getSignature2(String decice_id, String rand_str, String timestamp){
        //获取signature
        List<NameValuePair> signatureInParam = new ArrayList<>();
        signatureInParam.add(new BasicNameValuePair("app_id", "89962055"));
        signatureInParam.add(new BasicNameValuePair("app_secret", "pMHTUWAoOGSjaToIhHKwmQJKWZcAAvjN"));
        signatureInParam.add(new BasicNameValuePair("device_id", decice_id));
        signatureInParam.add(new BasicNameValuePair("rand_str", rand_str));
        signatureInParam.add(new BasicNameValuePair("timestamp", timestamp));
        List<String> newParams = new ArrayList<>();
        for (NameValuePair pair : signatureInParam) {
            newParams.add(pair.getName() + "=" + pair.getValue());
        }
        String newStr = Joiner.on("&").join(newParams);
        String signature = MD5Util.MD5(newStr);
        return signature;
    }

    public static String getAccessToken(HashMap<String, String> tokenMap, String timestamp, String rand_str, String signature, String decice_id, House365RestResponse response){
        //获取acceToken接口URl
        String getAccessTokenUrl = "http://api.400.house365.com/api/5aaf0c48ed105";
        List<NameValuePair> tokenInParam = new ArrayList<>();
        List<NameValuePair> tokenHeaderParam = new ArrayList<>();

        tokenInParam.add(new BasicNameValuePair("timestamp", timestamp));
        tokenInParam.add(new BasicNameValuePair("app_id", "12558119"));
        tokenInParam.add(new BasicNameValuePair("rand_str", rand_str));
        tokenInParam.add(new BasicNameValuePair("signature", signature));
        tokenInParam.add(new BasicNameValuePair("device_id", decice_id));
        List<String> newTokenParams = new ArrayList<>();
        for (NameValuePair pair : tokenInParam) {
            newTokenParams.add(pair.getName() + "=" + pair.getValue());
        }
        String newTokenUrl = getAccessTokenUrl + "?" + Joiner.on("&").join(newTokenParams);
        String tokenResult = "";
        try {
            tokenResult = HttpUtil.getHttpRequest(newTokenUrl, tokenMap, 100000, "utf-8");
            if (Strings.isNullOrEmpty(tokenResult)) {
                throw new ServiceException("get token failed");
            }
            JSONObject json = JSONObject.fromObject(tokenResult);
            JSONObject jo = json.getJSONObject("data");
            String access_token = jo.getString("access_token");
            return access_token;
        }catch (Exception e){
            LOG.error(e.getMessage(), e);
            response.setResult("0");
            response.setMsg(e.getMessage());
        }
        return null;
    }

    public static String postWithJson(JSONObject jsonObj, String url, String token) {
        HttpPost post = null;
        try {
            HttpClient httpClient = new DefaultHttpClient();

            post = new HttpPost(url);
            // 构造消息头
            post.setHeader("access_token", token);

            // 构建消息实体
            StringEntity entity = new StringEntity(jsonObj.toString(), Charset.forName("UTF-8"));
            entity.setContentEncoding("UTF-8");
            // 发送Json格式的数据请求
            entity.setContentType("application/json");
            post.setEntity(entity);

            HttpResponse response = httpClient.execute(post);

            // 检验返回码
            int statusCode = response.getStatusLine().getStatusCode();
            HttpEntity httpEntity = response.getEntity();
            String body = null;
            if (httpEntity != null && statusCode == HttpStatus.SC_OK ) {
                if (org.apache.commons.lang3.StringUtils.isNotBlank(DEFAULT_ENCODING)) {
                    body = EntityUtils.toString(httpEntity, DEFAULT_ENCODING);
                } else {
                    body = EntityUtils.toString(httpEntity, DEFAULT_ENCODING);
                }
                EntityUtils.consume(httpEntity);
            }
            return body;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (post != null) {
                try {
                    post.releaseConnection();
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
