package com.ruoyi.common.utils;

import com.ruoyi.common.exception.OkHttpException;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by admin on 2018/12/21.
 */
public class OkHttpUtils {

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    public static final MediaType MEDIA_TYPE = MediaType.parse("application/json;charset=utf-8");
    private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class);
    private static OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(20000, TimeUnit.MILLISECONDS)
            .readTimeout(20000, TimeUnit.MILLISECONDS)
            .build();

    public static String postJson(String url, String json) {
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder().url(url).post(body).build();
        String bodyStr = httpCall(request);
        return bodyStr;
    }

    public static String postJson(String url, String json, Map<String, String> headerMap) {
        String bodyStr = "";
        RequestBody body = RequestBody.create(MEDIA_TYPE, json);
        Headers headers = Headers.of(headerMap);
        Request request = new Request.Builder().url(url).post(body).headers(headers).build();
        bodyStr = httpCall(request);
        return bodyStr;
    }

    public static String postMap(String url, Map map, Map headerMap) {
        /* Long sTime = System.currentTimeMillis();*/
        try {
            FormBody.Builder builder = new FormBody.Builder();
            if (map != null && map.size() != 0) {
                for (Object obj : map.keySet()) {
                    if (map.get(obj) == null) {
                    } else {
                        builder.add(obj + "", map.get(obj).toString());
                    }
                }
            }
            RequestBody body = builder.build();
            Headers headers = Headers.of(headerMap);
            Request request = new Request.Builder().url(url).post(body).headers(headers).build();
            String bodyStr = httpCall(request);
            return bodyStr;
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage(), e);
            return "";
        }
    }

    public static String postMap(String url, Map map) {
        FormBody.Builder builder = new FormBody.Builder();
        if (map != null && map.size() != 0) {
            for (Object obj : map.keySet()) {
                if (map.get(obj) == null) {
                } else {
                    builder.add(obj + "", map.get(obj).toString());
                }
            }
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder().url(url).post(body).build();
        String bodyStr = httpCall(request);
        return bodyStr;
    }

    public static String get(String url) {
        Request request = new Request.Builder().url(url).build();
        String bodyStr = httpCall(request);
        return bodyStr;
    }

    public static String get(String url, Map headerMap) {
        Headers headers = Headers.of(headerMap);
        Request request = new Request.Builder().url(url).headers(headers).build();
        String bodyStr = httpCall(request);
        return bodyStr;
    }

    public static String getTimeUlr(String url) {
        client = new OkHttpClient.Builder().connectTimeout(1, TimeUnit.SECONDS).readTimeout(1, TimeUnit.SECONDS).build();
        Request request = new Request.Builder().url(url).build();
        return httpCall(request);
    }

    public static String getMap(String url, Map map) {
        if (map != null && map.size() != 0) {
            int i = 0;
            StringBuilder urlBuilder = new StringBuilder(url);
            for (Object obj : map.keySet()) {
                if (map.get(obj) != null) {
                    if (i == 0) {
                        urlBuilder.append("?");
                    } else {
                        urlBuilder.append("&");
                    }
                    urlBuilder.append(obj).append("=").append(map.get(obj));
                    i++;
                }
            }
            url = urlBuilder.toString();
        }
        Request request = new Request.Builder().url(url).get().build();
        return httpCall(request);
    }

    public static String getList(String url, List list) {
        String json = list.toString();
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder().url(url).get().put(body).build();
        String bodyStr = httpCall(request);
        return bodyStr;
    }

    public static File postFile(String url) {
        Request request = new Request.Builder().url(url).build();
        Response response = null;
        Call call = null;
        File file = new File("../report");
        try {
            call = client.newCall(request);
            response = call.execute();
            InputStream in = response.body().byteStream();
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[8096];
            int size = 0;
            while ((size = in.read(buf)) != -1) {
                fos.write(buf, 0, size);
            }
            fos.close();
        } catch (IOException e) {
            logger.info("请求失败----------------url:{}" + e, url);
        } finally {
            call.cancel();
        }
        return file;
    }

    public static void download(String url) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = null;
        Call call = null;
        File file = new File("../report");
        try {
            call = client.newCall(request);
            response = call.execute();
            InputStream in = response.body().byteStream();
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[8096];
            int size = 0;
            while ((size = in.read(buf)) != -1) {
                fos.write(buf, 0, size);
            }
            in.close();
            fos.flush();
            fos.close();
        } catch (IOException e) {
            logger.info("请求失败----------------url:{}" + e, url);
        } finally {
            call.cancel();
        }
    }

    public static String multipartHttpPost(String url, MultipartFile file, String filename, String name, Map<String, Object> param) {
        try {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            InputStream input = file.getInputStream();
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }
            RequestBody body = RequestBody.create(JSON, output.toByteArray());
            Request request = new Request.Builder()
                    .url(url).post(body)
                    .build();
            return httpCall(request);
        } catch (IOException e) {
            logger.error("url:{},参数：{}", url, e);
        }
        return null;
    }

    private static String httpCall(Request request) {
        Response response = null;
        Call call = null;
        try {
            call = client.newCall(request);
            response = call.execute();
            ResponseBody responseBody = response.body();
            return responseBody == null ? "" : responseBody.string();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new OkHttpException("request error", e);
        } finally {
            Optional.ofNullable(call).ifPresent(Call::cancel);
        }
    }

    /**
     * 把request转为map
     *
     * @param request
     * @return
     */
    public static Map<String, Object> getParameterMap(HttpServletRequest request) {
        // 参数Map
        Map<?, ?> properties = request.getParameterMap();
        // 返回值Map
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Iterator<?> entries = properties.entrySet().iterator();

        Map.Entry<String, Object> entry;
        String name = "";
        String value = "";
        Object valueObj = null;
        while (entries.hasNext()) {
            entry = (Map.Entry<String, Object>) entries.next();
            name = (String) entry.getKey();
            valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (String s : values) {
                    value = s + ",";
                }
                value = value.substring(0, value.length() - 1);
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }
}
