package com.virjar.g4proxy.utils;

import android.support.annotation.NonNull;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;

import java.io.IOException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.List;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * Created by liuzhaoce on 2019/4/12.
 */

public class HttpClientUtils {
    private static OkHttpClient client;
    private static OkHttpClient.Builder createBaseHttpClientBuilder() {
        //由于大量请求都是心跳请求，需要心跳keepAlive，同时考虑心跳时间间隔来确定链接存活时长
        ConnectionPool connectionPool = new ConnectionPool(5, 30, TimeUnit.SECONDS);
        return new OkHttpClient.Builder()

                .connectionPool(connectionPool)
                .retryOnConnectionFailure(false)
                .proxySelector(new ProxySelector() {
                    private List<Proxy> noProxyList = Lists.newArrayList(Proxy.NO_PROXY);

                    @Override
                    public List<Proxy> select(URI uri) {
                        //避免代理导致接口api通信失败
                        return noProxyList;
                    }

                    @Override
                    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {

                    }
                }).dispatcher(new Dispatcher(new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
                        new SynchronousQueue<Runnable>(), new ThreadFactory() {
                    @Override
                    public Thread newThread(@NonNull Runnable runnable) {
                        Thread result = new Thread(runnable, "OkHttp Dispatcher");
                        result.setDaemon(false);
                        //这里，如果网络handler发生了异常，那么只记录日志，而不进行程序中断
                        result.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                            @Override
                            public void uncaughtException(Thread t, Throwable e) {
                                Log.e("weijia", "network callback exception", e);
                            }
                        });
                        //result.setUncaughtExceptionHandler(LogedExceptionHandler.wrap(null));
                        return result;
                    }
                })));
    }


    public static OkHttpClient getClient() {
        if (client != null) {
            return client;
        }
        synchronized (HttpClientUtils.class) {
            if (client == null) {
                client = createBaseHttpClientBuilder()
                        .readTimeout(2, TimeUnit.SECONDS)
                        .connectTimeout(4, TimeUnit.SECONDS)
                        .writeTimeout(2, TimeUnit.SECONDS)
                        .build();
            }
        }
        return client;
    }


    public static Request getRequest(String url) {
        return new Request.Builder()
                .get()
                .url(url)
                .build();
    }

    public static Request postRequest(String url, org.json.JSONObject data){

        Log.e("postMsg", String.valueOf(data));
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(mediaType, data.toString());

        return new Request.Builder()
                .url(url)
                .post(body)
                .build();
    }
}
