package cn.com.ctop.crawler.modules.core.util;

import cn.com.ctop.common.module.entity.IpPool;
import cn.com.ctop.crawler.modules.core.entity.HttpBody;
import cn.com.ctop.crawler.modules.core.entity.HttpCookie;
import cn.com.ctop.crawler.modules.core.entity.HttpEntity;
import cn.com.ctop.crawler.modules.core.entity.HttpHeader;
import cn.com.ctop.crawler.modules.log.entity.CrawlerLog;
import com.google.gson.Gson;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
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.impl.cookie.BasicClientCookie;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

public class KuaishouUtil {
    public static CrawlerLog requestData(HttpEntity httpEntity, IpPool ipPool) {
        long beginTime = System.currentTimeMillis();
        CrawlerLog crawlerLog = new CrawlerLog();
        String salt = "382700b563f4";
        Map<String,String> staticParams = httpEntity.getHttpBody().getStaticParams();
        Map<String,String> dynamicParams = httpEntity.getHttpBody().getDynamicParams();
        List<String> ignoreKeyList = new ArrayList<String>();
        ignoreKeyList.add("sig");
        ignoreKeyList.add("__NS_sig3");
        ignoreKeyList.add("__NStokensig");
        String staticQueryString = HttpParamUtil.mapToUrlString(staticParams,null);
        Map<String,String> allMap = new HashMap<String,String>();
        allMap.putAll(staticParams);
        allMap.putAll(dynamicParams);
        if (staticParams.get("kpf") != null && "ANDROID_PHONE".equals(staticParams.get("kpf"))) {
            String sig = SignUtil.getMd5Sign(HttpParamUtil.mapToString(SortUtil.sortMapByKey(allMap), ignoreKeyList), salt);
            dynamicParams.put("sig",sig);
            allMap.put("sig",sig);
        }

        String dynamicQueryString = HttpParamUtil.mapToUrlStringNoEncoder(dynamicParams,null);
        BasicCookieStore cookieStore = new BasicCookieStore();
        for(HttpCookie cookie : httpEntity.getCookies()){
            BasicClientCookie clientCookie = new BasicClientCookie(cookie.getName(),cookie.getValue());
            clientCookie.setDomain(cookie.getDomain());
            clientCookie.setPath("/");
            cookieStore.addCookie(clientCookie);
        }
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有证书
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            RequestConfig globalConfig = null;
            SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext);
            if (ipPool != null) {
                HttpHost proxy = new HttpHost(ipPool.getIp(), ipPool.getPort(), "http");
                globalConfig = RequestConfig.custom().setProxy(proxy).setConnectTimeout(60000).setSocketTimeout(60000).setCookieSpec(CookieSpecs.STANDARD).build();
            } else {
                globalConfig = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(60000).setCookieSpec(CookieSpecs.STANDARD).build();
            }
            CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).setDefaultRequestConfig(globalConfig).setConnectionReuseStrategy((response, context) -> false ).setSSLSocketFactory(sslFactory).build();
            HttpPost httppost = new HttpPost(httpEntity.getUrl()+httpEntity.getPath()+"?"+staticQueryString);
            HttpHeader header = httpEntity.getHttpHeader();
            Map<String,String> headers = header.getHeaders();
            if(headers != null){
                for (String key:headers.keySet()){
                    httppost.addHeader(key,headers.get(key));
                }
            }
            httppost.setEntity(new StringEntity(dynamicQueryString));
            HttpResponse response = httpClient.execute(httppost);
            int code = response.getStatusLine().getStatusCode();
            org.apache.http.HttpEntity respentity = response.getEntity();
            String strReturn = EntityUtils.toString(respentity);
            long endTime = System.currentTimeMillis();
            crawlerLog.setUrl(httpEntity.getUrl());
            crawlerLog.setPath(httpEntity.getPath());
            crawlerLog.setMethod("POST");
            crawlerLog.setRequestBody(new Gson().toJson(allMap));
            crawlerLog.setRequestHeader(new Gson().toJson(httpEntity.getHttpHeader()));
            crawlerLog.setRequestCookie(new Gson().toJson(httpEntity.getCookies()));
            crawlerLog.setRequestStatus(response.getStatusLine().getStatusCode());
            crawlerLog.setResponseBody(strReturn);
            crawlerLog.setResponseHeader("");
            crawlerLog.setResponseCookie(new Gson().toJson(cookieStore));
            crawlerLog.setCreateTime(new Date(beginTime));
            crawlerLog.setRequestTime((int)(endTime-beginTime));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return crawlerLog;
    }
    private static String randomRequestId() {
        int temp = 436669999 - 436650000;
        int nextInt = new Random().nextInt(temp) + 436650000;
        return String.valueOf(nextInt);
    }

    public static CrawlerLog kuaishouAppDataFeatch(String url, String path, String urlParam, String bodyParam, String headerParam, String token, IpPool ipPool) {
        HttpEntity httpEntity = new HttpEntity();
        Map<String,String> staticParams = HttpParamUtil.urlParamToMap(urlParam);
        Map<String,String> dynamicParams = HttpParamUtil.urlParamToMap(bodyParam);
        List<HttpCookie> cookies = new ArrayList<>();
        HttpCookie cookie = new HttpCookie();
        cookie.setDomain(url.replace("https://","").replace("http://",""));
        cookie.setName("token");
        cookie.setPath("/");
        cookie.setValue(token);
        cookies.add(cookie);
        Map<String,String> headers = HttpParamUtil.urlParamToMap(headerParam);
        httpEntity.setCookies(cookies);
        httpEntity.setUrl(url);
        httpEntity.setPath(path);
        HttpHeader header = new HttpHeader();
        header.setHeaders(headers);
        HttpBody httpBody = new HttpBody();
        httpBody.setDynamicParams(dynamicParams);
        httpBody.setStaticParams(staticParams);
        httpEntity.setHttpHeader(header);
        httpEntity.setHttpBody(httpBody);
        return KuaishouUtil.requestData(httpEntity, ipPool);
    }
}
