package com.mogo.cloud.network.cronet

import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import org.chromium.net.CronetEngine
import org.chromium.net.ExperimentalCronetEngine
import org.chromium.net.NetworkQualityRttListener
import org.chromium.net.NetworkQualityThroughputListener
import java.util.concurrent.Executors

@SuppressLint("StaticFieldLeak")
object QuicConfig {
    private var engine: ExperimentalCronetEngine? = null
    private var converter: RequestResponseConverter? = null
    private var listener: NetworkQualityListener? = null
    private val executor by lazy {
        Executors.newFixedThreadPool(2)
    }

    @Volatile
    private var enable: Boolean = false
    private var isDebug: Boolean = false

    fun init(context: Context, isDebug: Boolean = false) {
        this.isDebug = isDebug
        if (engine == null) {
            engine = ExperimentalCronetEngine.Builder(context.applicationContext)
                .enableQuic(true)
                .enableHttp2(true)
                .enableNetworkQualityEstimator(true)
                .setUserAgent("OkHttp With Cronet")
                .build()
            engine?.addRttListener(object :
                NetworkQualityRttListener(executor) {
                // source请看注解NetworkQualityObservationSource,HTTP为0 TCP为1 QUIC为2
                override fun onRttObservation(rttMs: Int, whenMs: Long, source: Int) {
                    if (getDebug()) {
                        Log.d("CronetNetwork", "rttMs is:$rttMs ms,source is:$source")
                    }
                    getNetworkListener()?.onRttObservation(rttMs, whenMs, source)
                }
            })
            engine?.addThroughputListener(object : NetworkQualityThroughputListener(executor) {
                override fun onThroughputObservation(throughputKbps: Int, whenMs: Long, source: Int) {
                    if (getDebug()) {
                        Log.d("CronetNetwork", "downstream throughput is:$throughputKbps,source is:$source")
                    }
                    getNetworkListener()?.onThroughputObservation(throughputKbps, whenMs, source)
                }
            })
        }
        if (converter == null) {
            converter = RequestResponseConverter(
                engine,
                Executors.newFixedThreadPool(4),  // There must always be enough executors to blocking-read the OkHttp request bodies
                // otherwise deadlocks can occur.
                RequestBodyConverterImpl.create(Executors.newCachedThreadPool()),
                ResponseConverter(),
                RedirectStrategy.defaultStrategy()
            )
        }
    }

    fun getEnable(): Boolean {
        return enable
    }

    fun setEnable(context: Context, enable: Boolean, isDebug: Boolean = false) {
        when {
            enable -> {
                init(context, isDebug)
                this.enable = true
            }
            else -> {
                this.enable = false
            }
        }
    }

    fun getEngine(): CronetEngine? {
        return engine
    }

    fun getConverter(): RequestResponseConverter? {
        return converter
    }

    fun getDebug(): Boolean {
        return isDebug
    }

    fun setNetworkListener(listener: NetworkQualityListener) {
        this.listener = listener
    }

    fun getNetworkListener(): NetworkQualityListener? {
        return listener
    }
}