package com.softwarebr.nunu.util;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.http.HttpMethod;

import java.io.File;
import java.io.IOException;
import java.util.Map;

/**
 * Created by xu
 *
 * HTTP请求工具
 *
 * @author xu
 * @date 18-4-17 下午1:43
 */
@Slf4j
public class HttpUtils {

    //使用OKHTTP作为HTTP客户端
    private static OkHttpClient client;
    private static Gson gson = new Gson();
    static {
        File cacheDir = new File(System.getProperty("user.dir") + File.separator + "htt-cache");
        long cacheSize = 10 * 1024 * 1024;

        if(!cacheDir.exists()){
            cacheDir.mkdir();
        }
        client = new OkHttpClient.Builder()
                .cache(new Cache(cacheDir, cacheSize))
                .build();
    }

    /**
     * HTTP 请求
     * @param method  请求方法
     * @param server  服务器地址
     * @param uri     uri
     * @param headers 请求头
     * @param params  请求参数
     * @param body    请求体
     * @return
     */
    public static String request(HttpMethod method, String server,
                                 String uri, Map<String, String> headers,
                                 Map<String, String> params, String body) throws IOException {

        return performRequest(method, server, uri, headers, params, body).body().string();
    }

    public static Response performRequest(HttpMethod method, String server,
                                          String uri, Map<String, String> headers,
                                          Map<String, String> params, String body) throws IOException {
        Request.Builder build = new Request.Builder();
        if(body == null){
            build.method(method.name(), null);
        } else {
            build.method(method.name(),
                    RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), body));
        }

        String url;
        if(StringUtil.isNotEmpty(uri)){
            url = server + "/" + uri;
        } else {
            url = server;
        }

        if(headers != null && headers.size() != 0){
            for (String key : headers.keySet()) {
                build.addHeader(key, headers.get(key));
            }
        }
        if(params != null && params.size() != 0){
            StringBuilder paramsString = new StringBuilder();
            for (String key : params.keySet()) {
                paramsString.append(key);
                paramsString.append("=");
                paramsString.append(params.get(key));
                paramsString.append("&");
            }

            url += ("?" + paramsString.substring(0, paramsString.length() - 1));
        }

        build.url(url);

        Response response = client.newCall(build.build()).execute();
        if(!response.isSuccessful()){
            log.error("失败信息 url={}, code={}", url, response.code());
        }

        return response;
    }


    public static String request(HttpMethod method, String server,
                                 String uri, Map<String, String> headers, RequestBody body) throws IOException {

        Request.Builder build = new Request.Builder();
        build.method(method.name(), body);

        String url;
        if(StringUtil.isNotEmpty(uri)){
            url = server + "/" + uri;
        } else {
            url = server;
        }

        if(headers != null && headers.size() != 0){
            for (String key : headers.keySet()) {
                build.addHeader(key, headers.get(key));
            }
        }

        build.url(url);

        Response response = client.newCall(build.build()).execute();
        if(!response.isSuccessful()){
            log.error("失败信息 url={}, code={}", url, response.code());
        }

        return response.body().string();
    }

    public static String get(String url, Map<String, String> headers,
                      Map<String, String> params) throws IOException {
        return request(HttpMethod.GET, url, null, headers, params, null);
    }

    public static Response performGet(String url, Map<String, String> headers,
                                      Map<String, String> params) throws IOException {
        return performRequest(HttpMethod.GET, url, null, headers, params, null);
    }

    public static JsonObject jsonGet(String url, Map<String, String> headers,
                                 Map<String, String> params) throws IOException {
        return gson.fromJson(get(url, headers, params), JsonObject.class);
    }

    public static String post(String url, Map<String, String> headers,
                       Map<String, String> params, Object body) throws IOException {
        return request(HttpMethod.POST, url, null, headers, params, gson.toJson(body));
    }

    public static Response performPost(String url, Map<String, String> headers,
                                       Map<String, String> params, Object body) throws IOException {
        return performRequest(HttpMethod.POST, url, null, headers, params, gson.toJson(body));
    }

    public static String postFrom(String url, Map<String, String> headers, RequestBody requestBody) throws IOException {
        return request(HttpMethod.POST, url, null, headers, requestBody);
    }

    public static JsonObject jsonPostFrom(String url, Map<String, String> headers, RequestBody requestBody) throws IOException {
        return gson.fromJson(request(HttpMethod.POST, url, null, headers, requestBody),
                JsonObject.class);
    }

    public static JsonObject jsonPost(String url, Map<String, String> headers,
                                  Map<String, String> params, Object body) throws IOException{
        return gson.fromJson(
                request(HttpMethod.POST, url, null, headers, params, gson.toJson(body))
                , JsonObject.class
        );
    }

    public static String put(String url, Map<String, String> headers,
                       Map<String, String> params, Object body) throws IOException {
        return request(HttpMethod.PUT, url, null, headers, params, gson.toJson(body));
    }

    public static Response performPut(String url, Map<String, String> headers,
                                       Map<String, String> params, Object body) throws IOException {
        return performRequest(HttpMethod.PUT, url, null, headers, params, gson.toJson(body));
    }

    public static JsonObject jsonPut(String url, Map<String, String> headers,
                                      Map<String, String> params, Object body) throws IOException{
        return gson.fromJson(
                request(HttpMethod.PUT, url, null, headers, params, gson.toJson(body))
                , JsonObject.class
        );
    }

    public static String delete(String url, Map<String, String> headers,
                       Map<String, String> params, Object body) throws IOException {
        return request(HttpMethod.DELETE, url, null, headers, params, gson.toJson(body));
    }

    public static Response performDelete(String url, Map<String, String> headers,
                                      Map<String, String> params, Object body) throws IOException {
        return performRequest(HttpMethod.DELETE, url, null, headers, params, gson.toJson(body));
    }

    public static JsonObject jsonDelete(String url, Map<String, String> headers,
                                     Map<String, String> params, Object body) throws IOException{
        return gson.fromJson(
                request(HttpMethod.DELETE, url, null, headers, params, gson.toJson(body))
                , JsonObject.class
        );
    }

    /**
     * 生成FormBody
     * @param params
     * @return
     */
    public static FormBody genFormBody(Map<String, String> params){
        FormBody.Builder builder = new FormBody.Builder();
        for (String key : params.keySet()) {
            builder.addEncoded(key, params.get(key));
        }

        return builder.build();
    }



}
