package com.huigou.topsun.sap.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.huigou.cache.SystemCache;
import com.huigou.topsun.sap.common.serializer.MessageSerializer;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.util.StringUtil;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Base64;

/**
 */
@Component
public class DefaultHttpClient extends BaseApplication implements HttpClient {

    private final static Logger LOG = LoggerFactory.getLogger(DefaultHttpClient.class);
    private final MessageSerializer messageSerializer;
    private final org.apache.http.client.HttpClient http = HttpClientBuilder.create().build();

    @Autowired
    public DefaultHttpClient(MessageSerializer messageSerializer) {
        this.messageSerializer = messageSerializer;
    }

    /**
     * 访问SAP系统的ip、上下文httpClient配置
     * @param param 非JSON数据对象
     * @param url 控制层地址
     * @return 返回
     * @throws IOException
     */
    @Override
    public String execute(Object param,String url) throws IOException {
        //系统接口地址
        //  ip地址
        String ip = SystemCache.getParameter("sap.service.ip", String.class);
        //  上下文
        String applicationContext = SystemCache.getParameter("sap.service.application.context", String.class);
        //  用户名
        String password = SystemCache.getParameter("sap.service.password", String.class);
        //  密码
        String username = SystemCache.getParameter("sap.service.username", String.class);
        //  客户端
        String client = SystemCache.getParameter("sap.service.client", String.class);
        //String serverUrl = "http://192.168.3.109:8000/sap/bc/erp_ep/bd_mastdata/material?sap-client=200";
        StringBuffer serverUrl = new StringBuffer();
        serverUrl
                .append(ip)
                .append(applicationContext)
                .append(url)
                .append("?")
                .append(client)
                .append("&sap-language=ZH");
        String usernameAndPassword = username + ":" + password;
        return this.buildHttpClient(param, String.valueOf(serverUrl),usernameAndPassword);
    }

    /**
     * 访问EP系统的ip、上下文httpClient配置
     * @param param 非JSON数据对象
     * @param url 控制层地址
     * @return 返回
     * @throws IOException
     */
    @Override
    public String executeForEp(Object param,String url) throws IOException {
        return this.buildHttpClient(param, getEPHttpUrlMsg(url),"");
    }

    @Override
    public String executeHttpGetForEp(Object param, String url) throws IOException {
        return this.buildHttpGetClient(param, getEPHttpUrlMsg(url),"");
    }

    /**
     * 返回URL拼接
     * @param url
     * @return
     */
    public String getEPHttpUrlMsg(String url){
        //系统接口地址
        //  ip地址
        String ip = SystemCache.getParameter("ep.service.ip", String.class);
        //  上下文
        String applicationContext = SystemCache.getParameter("ep.service.application.context", String.class);
        //String serverUrl = "http://192.168.23.15:8080/api/od/saleOrder/auditedResult.ajax";
        StringBuffer serverUrl = new StringBuffer();
        serverUrl
                .append(ip)
                .append(applicationContext)
                .append(url);
        return String.valueOf(serverUrl);
    }

    /**
     * 访问MES系统的ip、上下文httpClient配置
     * @param param 非JSON数据对象
     * @param url 控制层地址
     * @return 返回
     * @throws IOException
     */
    @Override
    public String executeForMes(Object param,String url) throws IOException {
        MesHttpUrlMsg httpUrlMsg = this.getHttpUrlMsg(url);
        return this.buildHttpClient(param, httpUrlMsg.getUrl(),httpUrlMsg.getUsernameAndPassword());
    }

    /**
     * 访问MES系统的ip、上下文httpClient配置
     * @param param 非JSON数据对象
     * @param url 控制层地址
     * @return 返回
     * @throws IOException
     */
    @Override
    public String executeHttpGetForMes(Object param,String url) throws IOException {
        MesHttpUrlMsg httpUrlMsg = this.getHttpUrlMsg(url);
        return this.buildHttpGetClient(param, httpUrlMsg.getUrl(),httpUrlMsg.getUsernameAndPassword());
    }

    /**
     * 返回URL拼接
     * @param url
     * @return
     */
    public MesHttpUrlMsg getHttpUrlMsg(String url){
        //系统接口地址
        //  ip地址
        String ip = SystemCache.getParameter("mes.service.ip", String.class);
        //  上下文
        String applicationContext = SystemCache.getParameter("mes.service.application.context", String.class);
        String username = SystemCache.getParameter("mes.service.username", String.class);
        String password = SystemCache.getParameter("mes.service.password", String.class);
        String usernameAndPassword = username + ":" + password;
        //String serverUrl = "http://192.168.23.15:8080/api/od/saleOrder/auditedResult.ajax";
        StringBuffer serverUrl = new StringBuffer();
        serverUrl
                .append(ip)
                .append(applicationContext)
                .append(url);
        return new MesHttpUrlMsg(String.valueOf(serverUrl),usernameAndPassword);
    }

    /**
     *
     * @param obj  非JSON数据对象
     * @param serverUrl 服务拼接地址
     * @param usernameAndPassword 用户名密码拼接
     * @return
     * @throws IOException
     */
    public String buildHttpClient(Object obj,String serverUrl,String usernameAndPassword) throws IOException {
        HttpPost post = new HttpPost(serverUrl);
        post.setHeader("Content-type", "application/json;charset=utf-8");
        //String usernameAndPassword = username + ":" + password;
        if (StringUtil.isNotBlank(usernameAndPassword)){
            post.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString(usernameAndPassword.getBytes()));
        }
        String paramJson = new ObjectMapper().writeValueAsString(obj);
        LOG.info("requestText={}", paramJson);
        post.setEntity(new StringEntity(paramJson, ContentType.APPLICATION_JSON));
        LOG.info("post={}", post);
        HttpResponse response;
        String responseText = "";
        try {
            response = http.execute(post);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusLine.getStatusCode() < HttpStatus.SC_OK || statusLine.getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
                throw new IOException(String.format("调用系统出错，statusCode=%s, %s", statusCode, statusLine.getReasonPhrase()));
            }
            responseText = EntityUtils.toString(response.getEntity(), "UTF-8");
            LOG.info("responseText={}", responseText);
        }finally {
            post.releaseConnection();
        }
        return responseText;
    }

    /**
     *
     * @param obj  非JSON数据对象
     * @param serverUrl 服务拼接地址
     * @param usernameAndPassword 用户名密码拼接
     * @return
     * @throws IOException
     */
    public String buildHttpGetClient(Object obj,String serverUrl,String usernameAndPassword) throws IOException {
        HttpGet get = new HttpGet(serverUrl);
        get.setHeader("Content-type", "application/json;charset=utf-8");
        //String usernameAndPassword = username + ":" + password;
        if (StringUtil.isNotBlank(usernameAndPassword)){
            get.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString(usernameAndPassword.getBytes()));
        }
        LOG.info("get={}", get);
        HttpResponse response;
        String responseText = "";
        try {
            response = http.execute(get);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
                throw new IOException(String.format("调用系统出错，statusCode=%s, %s", statusCode, statusLine.getReasonPhrase()));
            }
            responseText = EntityUtils.toString(response.getEntity(), "UTF-8");
            LOG.info("responseText={}", responseText);
        }finally {
            get.releaseConnection();
        }
        return responseText;
    }

}
