package ru.fincode.tsudesk.core.network

import android.annotation.SuppressLint
import okhttp3.OkHttpClient
import ru.fincode.tsudesk.core.common.app.AppConfig
import ru.fincode.tsudesk.core.network.interceptor.DebugInterceptor
import ru.fincode.tsudesk.core.network.interceptor.NetEventLogger
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
import javax.net.ssl.*

@Singleton
class OkHttpClientFactory @Inject constructor(
    private val appConfig: AppConfig,
    private val debugInterceptor: DebugInterceptor
) {

    fun create(): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .connectTimeout(appConfig.networkTimeoutSec, TimeUnit.SECONDS)
            .readTimeout(appConfig.networkTimeoutSec, TimeUnit.SECONDS)
            .writeTimeout(appConfig.networkTimeoutSec, TimeUnit.SECONDS)
            .retryOnConnectionFailure(false)

        if (appConfig.isDebug) {
            builder.addInterceptor(debugInterceptor)
            applyUnsafeSslForDebug(builder)
            builder.eventListenerFactory { NetEventLogger() }
        }

        return builder.build()
    }

    private fun applyUnsafeSslForDebug(builder: OkHttpClient.Builder) {
        val trustManager = @SuppressLint("CustomX509TrustManager")
        object : X509TrustManager {

            override fun checkClientTrusted(
                chain: Array<X509Certificate>,
                authType: String
            ) = Unit

            override fun checkServerTrusted(
                chain: Array<X509Certificate>,
                authType: String
            ) = Unit

            override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray()
        }

        val sslContext = SSLContext.getInstance("SSL").apply {
            init(null, arrayOf<TrustManager>(trustManager), SecureRandom())
        }

        builder.sslSocketFactory(
            sslContext.socketFactory,
            trustManager
        )

        builder.hostnameVerifier { _, _ -> true }
    }
}
