package com.mogo.cloud.network

import okhttp3.*
import okhttp3.EventListener.Factory
import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Proxy

class WeakNetworkEventFactory {
    companion object {
        val FACTORY by lazy {
            Factory { WeakNetworkEventListener() }
        }

        private var listener: OnHttpRttListener? = null

        internal fun setListener(httpRttListener: OnHttpRttListener?) {
            listener = httpRttListener
        }
    }

    private class WeakNetworkEventListener: EventListener() {

        private var timeStamp: Long = 0

        override fun callStart(call: Call) {
            super.callStart(call)
            timeStamp = System.currentTimeMillis()
        }

        override fun dnsStart(call: Call, domainName: String) {
            super.dnsStart(call, domainName)
        }

        override fun dnsEnd(
            call: Call,
            domainName: String,
            inetAddressList: MutableList<InetAddress>
        ) {
            super.dnsEnd(call, domainName, inetAddressList)
        }

        override fun connectFailed(
            call: Call,
            inetSocketAddress: InetSocketAddress,
            proxy: Proxy,
            protocol: Protocol?,
            ioe: IOException
        ) {
            super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe)
            listener?.onFailEvent(this.hashCode(), call.request().url().toString(), System.currentTimeMillis() - timeStamp)
        }

        override fun responseHeadersStart(call: Call) {
            super.responseHeadersStart(call)
        }

        override fun responseHeadersEnd(call: Call, response: Response) {
            super.responseHeadersEnd(call, response)
            listener?.onHttpRttReceived(this.hashCode(), call.request().url().toString(), System.currentTimeMillis() - timeStamp)
        }

        override fun responseBodyStart(call: Call) {
            super.responseBodyStart(call)
        }

        override fun responseBodyEnd(call: Call, byteCount: Long) {
            super.responseBodyEnd(call, byteCount)
        }

        override fun connectionReleased(call: Call, connection: Connection) {
            super.connectionReleased(call, connection)
        }

        override fun callFailed(call: Call, ioe: IOException) {
            super.callFailed(call, ioe)
        }

        override fun callEnd(call: Call) {
            super.callEnd(call)
        }
    }

    internal interface OnHttpRttListener {
        fun onHttpRttReceived(hashCode: Int, url: String, timeStamp: Long)

        fun onFailEvent(hashCode: Int, url: String, timeStamp: Long)
    }
}