package com.xhly.corelib.network

import android.annotation.SuppressLint
import android.util.Log
import com.xhly.corelib.Const
import io.reactivex.internal.subscribers.DeferredScalarSubscriber
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.net.Proxy
import java.net.URLDecoder
import java.net.URLEncoder
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

object RetrofitService {
    private const val READ_TIMEOUT = 60L
    private const val WRITE_TIMEOUT = 60L
    private const val CONNECT_TIMEOUT = 30L

    var BASE_URL = Const.URL1

    private var mRetrofit: Retrofit? = null

    private fun getClient(): OkHttpClient {

        val interceptor = HttpLoggingInterceptor { message ->
            try {
                val text: String = URLDecoder.decode(message, "utf-8")
                Log.e("OKHttp-----", text)
            } catch (t: Exception) {
                try {
                    var encode = URLEncoder.encode(message, "utf-8")
                    val text: String = URLDecoder.decode(encode, "utf-8")
                    Log.e("OKHttp-----DEBUG", text)
                } catch (e: Exception) {
                    t.printStackTrace()
                    e.printStackTrace()
                }
            }
        }
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        return OkHttpClient.Builder()
           /* .proxy(Proxy.NO_PROXY)*/
            .retryOnConnectionFailure(true)
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .sslSocketFactory(getSSLSocketFactory(), trustManager)
            .addInterceptor(ResponseInterceptor())
            .addInterceptor(interceptor).build()
    }

    fun getRetrofit(): Retrofit {
        return mRetrofit ?: Retrofit.Builder().baseUrl(BASE_URL).validateEagerly(true)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .client(getClient()).build().also { mRetrofit = it }
    }

    @kotlin.jvm.Throws(Exception::class)
    private fun getSSLSocketFactory(): SSLSocketFactory {
        //创建一个不验证证书链的证书信任管理器。
        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
            @kotlin.jvm.Throws(CertificateException::class)
            override fun checkClientTrusted(
                chain: Array<X509Certificate>,
                authType: String
            ) {
            }

            @kotlin.jvm.Throws(CertificateException::class)
            override fun checkServerTrusted(
                chain: Array<X509Certificate>,
                authType: String
            ) {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate?> {
                return arrayOfNulls(0)
            }
        })

        // Install the all-trusting trust manager
        val sslContext = SSLContext.getInstance("TLS")
        sslContext.init(
            null, trustAllCerts,
            SecureRandom()
        )
        // Create an ssl socket factory with our all-trusting manager
        return sslContext.socketFactory
    }

    val trustManager = @SuppressLint("CustomX509TrustManager")
    object : X509TrustManager {
        @SuppressLint("TrustAllX509TrustManager")
        @Throws(CertificateException::class)
        override fun checkClientTrusted(
            chain: Array<X509Certificate>,
            authType: String
        ) {
        }

        @SuppressLint("TrustAllX509TrustManager")
        @Throws(CertificateException::class)
        override fun checkServerTrusted(
            chain: Array<X509Certificate>,
            authType: String
        ) {
        }

        override fun getAcceptedIssuers(): Array<X509Certificate?> {
            return arrayOfNulls(0)
        }
    }


    inline fun <reified T> create() = getRetrofit().create(T::class.java)
}