package com.uas.finance.util;

import com.alibaba.fastjson.JSONObject;
import com.uas.platform.core.util.serializer.FlexJsonUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
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.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by hejq on 2017-10-10.
 */
public class FileUploadHttp {
    /**
     * 发起POST、PUT请求
     *
     * @param request
     * @param params
     * @return
     * @throws Exception
     */
    public static Response get(String url, Map<String, Object> params) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpEntityEnclosingRequestBase request = null;
        CloseableHttpResponse response = null;
        try {
            StringBuilder buf = new StringBuilder(url);
            if (params != null && !params.isEmpty()) {
                if (url.indexOf("?") == -1)
                    buf.append("?");
                else if (!url.endsWith("&"))
                    buf.append("&");
                Set<Map.Entry<String, Object>> entrys = params.entrySet();
                for (Map.Entry<String, Object> entry : entrys) {
                    buf.append(entry.getKey()).append("=").append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8")).append("&");
                }
            }
            request = new HttpPost(buf.toString());
            response = httpClient.execute(request);
            return Response.getResponse(response);
        } finally {
            request.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * 发起POST、PUT请求
     *
     * @param request
     * @param datas
     * @return
     * @throws Exception
     */
    public static Response post(String url, Collection<?> datas) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpEntityEnclosingRequestBase request = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            if (datas != null && !datas.isEmpty()) {
                request.setEntity(new StringEntity(FlexJsonUtils.toJson(datas), ContentType.create("text/plain", Consts.UTF_8)));
            }
            response = httpClient.execute(request);
            return Response.getResponse(response);
        } finally {
            request.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * 发起POST、PUT请求
     *
     * @param request
     * @param params
     * @return
     * @throws Exception
     */
    public static Response post(String url, Map<String, String> params) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpEntityEnclosingRequestBase request = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            if (params != null && !params.isEmpty()) {
                Set<Map.Entry<String, String>> entrys = params.entrySet();
                for (Map.Entry<String, String> entry : entrys) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), URLEncoder.encode(entry.getValue(), "UTF-8")));
                }
            }
            request.setEntity(new UrlEncodedFormEntity(nvps));
            response = httpClient.execute(request);
            return Response.getResponse(response);
        } finally {
            request.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * http上传文件
     *
     * @param url
     *            请求地址
     * @param multipartFile
     *            附件路径
     * @param params
     *            参数
     * @return
     * @throws Exception
     * @throws IOException
     * @throws IllegalStateException
     */
    public static String upload(String url, MultipartFile multipartFile, Map<String, String> params) throws IllegalStateException, IOException,
            Exception {
        String path = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            InputStreamBody streamBody = new InputStreamBody(multipartFile.getInputStream(),
                    multipartFile.getOriginalFilename());
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addPart("file", streamBody);
            if (params != null) {
                for (String paramKey : params.keySet()) {
                    StringBody body = new StringBody(params.get(paramKey), ContentType.create("text/plain", Consts.UTF_8));
                    builder.addPart(paramKey, body);
                }
            }
            HttpEntity reqEntity = builder.build();
            httpPost.setEntity(reqEntity);
            response = httpClient.execute(httpPost);
            Response res = Response.getResponse(response);
            if(res.getStatusCode() == 200) {
                JSONObject obj = JSONObject.parseObject(res.getResponseText());
                path = (String) obj.get("path");
            }
            return path;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 下载
     *
     * @param url
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static InputStream download(String url) throws ClientProtocolException, IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        return response.getEntity().getContent();
    }

    public static class Response {
        private int statusCode;
        private String responseText;

        public int getStatusCode() {
            return statusCode;
        }

        public void setStatusCode(int statusCode) {
            this.statusCode = statusCode;
        }

        public String getResponseText() {
            return responseText;
        }

        public void setResponseText(String responseText) {
            this.responseText = responseText;
        }

        public Response() {
        }

        public Response(HttpResponse response) throws IllegalStateException, IOException, Exception {
            this.statusCode = response.getStatusLine().getStatusCode();
            this.responseText = IOUtils.toString(response.getEntity().getContent());
        }

        public static Response getResponse(HttpResponse response) throws IllegalStateException, IOException, Exception {
            if (response != null)
                return new Response(response);
            return null;
        }
    }
}
