package com.diaoyun.zion.master.util;

import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.google.common.collect.Lists;
import com.mashape.unirest.http.Unirest;
import org.apache.http.*;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HttpClientUtil {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    /**
     * 获取url链接中的content 内容
     *
     * @param sourceUrl  目标url
     * @param sourceType
     * @return
     * @throws URISyntaxException
     * @throws IOException
     */
    public static String getContentByUrl(String sourceUrl, String sourceType) throws URISyntaxException, IOException {
        sourceUrl = urlEncode(sourceUrl, Consts.UTF_8.name());
        URL url = new URL(sourceUrl);
        //构建URI
        URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
        //创建一个HttpContext对象，用来保存Cookie
        //HttpClientContext httpClientContext = HttpClientContext.create();
        //构造自定义的HttpClient对象
        CloseableHttpClient httpClient;
        if (PlatformEnum.TB.getValue().equals(sourceType)) {
            httpClient = createBrowserClient();
        } else if (PlatformEnum.TM.getValue().equals(sourceType)) {
            //天猫用手机端访问拿的数据 香港服务器不可行
            httpClient = createIphoneClient();
            //httpClient= createBrowserClient();
        } else {
            httpClient = createBrowserClient();
        }

        /* 构造请求对象 */
        HttpUriRequest httpUriRequest = RequestBuilder.get().setUri(uri).build();
        /* ****************获取商品详情链接******************* */
        //执行请求，传入HttpContext，将会得到请求结果的信息
        //httpClient.execute(httpUriRequest,httpClientContext)

        HttpResponse httpResponse = httpClient.execute(httpUriRequest);
        //拿到返回的HttpResponse的"实体"
        HttpEntity result = httpResponse.getEntity();
        //System.getProperties().list(System.out);//输出当前环境属性 55555555
        /*if(result.getContentEncoding()!=null) {
            if ("gzip".equalsIgnoreCase(result.getContentEncoding().getValue())) {
                result = new GzipDecompressingEntity(result);
            } else if ("deflate".equalsIgnoreCase(result.getContentEncoding().getValue())) {
                result = new DeflateDecompressingEntity(result);
            }
        }*/
        String defaultCharset = Consts.UTF_8.name();
        if (PlatformEnum.TM.getValue().equals(sourceType)) {
            defaultCharset = Consts.UTF_8.name();
        }
        String content = EntityUtils.toString(result, defaultCharset);
        //logger.info(content);
        //关闭连接
        httpClient.close();
        return content;
    }

    /**
     * 获取url链接中的content 网页内容
     *
     * @param url 目标url
     * @return
     * @throws URISyntaxException
     * @throws IOException
     */
    public static String getContentByUrl(String url, BasicHeader basicHeader) throws URISyntaxException, IOException {
        URI sibUri = new URIBuilder(url).build();
        //构造请求对象
        HttpUriRequest sibUriRequest = RequestBuilder.get().setUri(sibUri).build();
        //构造自定义的HttpClient对象
        CloseableHttpClient sibClient = createBrowserClient(basicHeader);
        //创建一个HttpContext对象，用来保存Cookie
        //HttpClientContext sibClientContext = HttpClientContext.create();
        //执行请求，传入HttpContext，将会得到请求结果的信息
        HttpResponse sibResponse = sibClient.execute(sibUriRequest);
        //拿到返回的HttpResponse的"实体"
        HttpEntity sibResult = sibResponse.getEntity();
        String sibContent = EntityUtils.toString(sibResult);
        //unicode 解码
        //关闭连接
        sibClient.close();
        return sibContent;
    }

    /**
     * 创建带浏览器头部的连接
     *
     * @return
     */
    public static CloseableHttpClient createBrowserClient() {
        //构造自定义Header信息
        List<Header> headerList = Lists.newArrayList();
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"));
        headerList.add(new BasicHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"));
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br"));
        headerList.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "max-age=0"));
        headerList.add(new BasicHeader(HttpHeaders.CONNECTION, "keep-alive"));
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9"));
        headerList.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8"));
        //cookie
        CookieStore cookieStore = new BasicCookieStore();
        return HttpClients.custom().setDefaultHeaders(headerList).setDefaultCookieStore(cookieStore).build();
    }

    /**
     * 创建带浏览器头部的连接
     *
     * @return
     */
    public static CloseableHttpClient createBrowserClient(BasicHeader basicHeader) {
        //构造自定义Header信息
        List<Header> headerList = Lists.newArrayList();
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9," +
                "image/webp,image/apng,*/*;q=0.8"));
        headerList.add(new BasicHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"));
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br"));
        headerList.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "max-age=0"));
        headerList.add(new BasicHeader(HttpHeaders.CONNECTION, "keep-alive"));
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9"));
        headerList.add(basicHeader);
        //cookie
        CookieStore cookieStore = new BasicCookieStore();
        return HttpClients.custom().setDefaultHeaders(headerList).setDefaultCookieStore(cookieStore).build();
    }

    /**
     * 创建带苹果手机头部的连接
     *
     * @return
     */
    public static CloseableHttpClient createIphoneClient() {
        //构造自定义Header信息
        List<Header> headerList = Lists.newArrayList();
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"));
        headerList.add(new BasicHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"));
        //headerList.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br"));
        headerList.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "max-age=0"));
        headerList.add(new BasicHeader(HttpHeaders.CONNECTION, "keep-alive"));
        headerList.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9"));
        //cookie
        CookieStore cookieStore = new BasicCookieStore();
        return HttpClients.custom().setDefaultHeaders(headerList).setDefaultCookieStore(cookieStore).build();
    }

    /**
     * 发送请求
     *
     * @param url
     * @param paramMap
     * @param charset
     * @return
     */
    public static String createConnection(String url, Map<String, Object> paramMap, String charset) throws IOException {
        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, charset);
        // 构建一个GET请求
        HttpGet httpGet = new HttpGet();
        httpGet.setURI(URI.create(url + "?" + param));
        CloseableHttpClient httpClient = createBrowserClient();
        HttpResponse sibResponse = httpClient.execute(httpGet);
        // 拿到返回的HttpResponse的"实体"
        HttpEntity sibResult = sibResponse.getEntity();
        return EntityUtils.toString(sibResult);
    }

    /**
     * 设置 Http 参数
     *
     * @param paramsMap
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, Object> paramsMap) {
        List<NameValuePair> list = new ArrayList<>();
        for (Map.Entry<String, Object> stringObjectEntry : paramsMap.entrySet()) {
            String key = stringObjectEntry.getKey();
            String value = (String) stringObjectEntry.getValue();
            list.add(new BasicNameValuePair(key, value));
        }
        return list;
    }

    /**
     * 获取连接中的参数
     *
     * @param targetUrl
     * @return
     */
    public static Map<String, String> getParamMap(String targetUrl) throws URISyntaxException, MalformedURLException {
        URL url = new URL(targetUrl);
        //构建URI
        URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
        List<NameValuePair> params = URLEncodedUtils.parse(uri, String.valueOf(Charset.forName(Consts.UTF_8.name())));
        Map<String, String> paramMap = new HashMap<>();
        for (NameValuePair param : params) {
            paramMap.put(param.getName(), param.getValue());
        }
        return paramMap;
    }

    /**
     * 发送带body参数的post请求
     *
     * @param url
     * @param paramMap
     * @return
     * @throws URISyntaxException
     * @throws IOException
     */
    public static String sendPostWithBodyParameter(String url, Map<String, Object> paramMap) throws IOException {
        //构建一个Post请求
        HttpPost httpPost = new HttpPost();
        httpPost.setURI(URI.create(url));
        httpPost.setHeader("Content-Type", "application/json");
        //放参数
        StringEntity entity = new StringEntity(GsonUtil.GsonString(paramMap), ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        //构造自定义的HttpClient对象
        CloseableHttpClient sibClient = HttpClients.custom().build();
        //执行请求，传入HttpContext，将会得到请求结果的信息
        HttpResponse sibResponse = sibClient.execute(httpPost);
        //拿到返回的HttpResponse的"实体"
        HttpEntity sibResult = sibResponse.getEntity();
        String sibContent = EntityUtils.toString(sibResult);
        //unicode 解码
        //关闭连接
        sibClient.close();
        return sibContent;
    }

    /**
     * 对链接进行url编码
     *
     * @param url
     * @param chartSet
     * @return
     */
    public static String urlEncode(String url, String chartSet) {
        try {
            //双字节,包括中文和中文符号[^\x00-\xff]  中文[\u4e00-\u9fa5]
            Matcher matcher = Pattern.compile("[^\\x00-\\xff]").matcher(url);
            while (matcher.find()) {
                String tmp = matcher.group();
                url = url.replaceAll(tmp, java.net.URLEncoder.encode(tmp, chartSet));
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("双字节编码异常：", e);
        }
        return url;
    }


    /**
     * 发送请求
     *
     * @param url
     * @param paramMap
     * @param charset
     * @return
     */
    public static String getConnection(String url, Map<String, Object> paramMap, String charset) throws IOException {

        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, charset);
        // 构建一个GET请求
        HttpGet httpGet = new HttpGet();
        httpGet.setURI(URI.create(url + "?" + param));
        CloseableHttpClient httpClient = createBrowserClient();
        HttpResponse sibResponse = httpClient.execute(httpGet);
        // 拿到返回的HttpResponse的"实体"
        HttpEntity sibResult = sibResponse.getEntity();
        Header header = sibResult.getContentEncoding();
        return EntityUtils.toString(sibResult) + "#" + header;
    }

    /**
     * 获取shopify接口 headers里的参数【Link】
     *
     * @param url
     * @return
     * @throws Exception
     */
    public static List<String> getHeaders(String url) throws Exception {
        List<String> list = new ArrayList();
        com.mashape.unirest.http.HttpResponse<String> response = Unirest.get(url)
                .headers(new HashMap<>())
                .asString();
        List<String> link = response.getHeaders().get("Link");
        String linkString = link.toString();
        boolean next = linkString.contains("next");
        boolean previous = linkString.contains("previous");
        String str = link.get(0);
        String[] split = str.split(",");
        for (int i = 0; i < split.length; i++) {
            String s = split[i];
            String sub = s.substring(s.indexOf("page_info="), s.lastIndexOf(">;"));
            String substring = sub.substring(10);
            list.add(substring);
        }
        if (next) {
            list.add("first");
            if (previous) {
                list.add("middle");
            }
        } else {
            list.add("last");
        }
        return list;
    }
}
