package com.mogo.v2x.config

import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.v2x.executor.Executors
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import kotlin.IllegalStateException

/**
 * V2X相关配置
 */
class V2XConfig private constructor(builder: Builder) {

    /**
     * - 应用上下文
     * - 必选项
     * - 通过[Builder.context]设置
     */
    val context : Context by lazy {
        builder.context?.applicationContext ?: throw IllegalStateException("context must not be null.")
    }

    /**
     * - 云平台配置参数
     * - 必选项
     * - 通过[Builder.aiCloudConfig]设置
     */
    val aiCloudConfig by lazy {
        builder.aiCloudConfig ?: throw IllegalStateException("aiCloudConfig must not be null.")
    }

    /**
     * - 网络请求使用的线程池，IO类型
     * - 可选项
     * - 通过[Builder.executor]设置
     */
    val executor: Executor by lazy {
        builder.executor ?: Executors.IO
    }

    /**
     * - 是否开启日志
     * - 可选项
     * - 通过[Builder.loggable]设置，开发阶段可以打开，应用发布后记得关闭
     */
    val loggable: Boolean by lazy {
        builder.loggable
    }

    /**
     * - 公共参数, 默认为空
     * - 可选项
     * - 通过[Builder.staticParams]设置
     */
    val staticParams by lazy {
        builder.staticParams ?: HashMap<String, Any>()
    }

    /**
     * - 基础Url, 默认值为`http://dzt-launcherSnapshot.zhidaozhixing.com`
     * - 可选项
     * - 通过[Builder.baseUrl]设置
     */
    val baseUrl by lazy {
        builder.baseUrl ?: "http://eagle-dns.zhidaozhixing.com/"

    }

    /**
     * - 多长时间请求一次自车周边信息，单位为毫秒，默认值为`6_000`毫秒
     * - 可选项
     * - 通过[Builder.durationForTriggerRefresh]设置
     */
    val durationForTriggerRefresh by lazy {
        val duration = builder.durationForTriggerRefresh
        if (duration == null || duration <= 0) TimeUnit.SECONDS.toMillis(60) else duration
    }

    /**
     * - 自车行驶超过此长度，会刷新自车周边信息，单位为`米`
     * - 可选项
     * - 通过[Builder.distanceForTriggerRefresh]设置
     */
    val distanceForTriggerRefresh: Float by lazy {
        val distance = builder.distanceForTriggerRefresh
        if (distance == null || distance <= 0) 200f else distance
    }

    internal fun newBuilder() = Builder(this)

    class Builder {

        internal var context: Context? = null

        internal var executor: Executor? = null

        internal var loggable: Boolean = false

        internal var staticParams: Map<String, Any?>? = null

        internal var aiCloudConfig: MoGoAiCloudClientConfig? = null

        internal var durationForTriggerRefresh: Long? = null

        internal var baseUrl: String? = null

        internal var distanceForTriggerRefresh: Float? = null

        constructor()

        internal constructor(config: V2XConfig)  {
            context = config.context
            executor = config.executor
            loggable = config.loggable
            baseUrl = config.baseUrl
            staticParams = config.staticParams
            aiCloudConfig = config.aiCloudConfig
            durationForTriggerRefresh = config.durationForTriggerRefresh
            distanceForTriggerRefresh = config.distanceForTriggerRefresh
        }

        /**
         * 应用上下文，此参数为必选项，不设置会抛异常
         */
        fun context(context: Context) = apply { this.context = context }

        /**
         * 是否开启日志
         */
        fun loggable(loggable: Boolean) = apply { this.loggable = loggable }

        /**
         * 公共参数列表
         */
        fun staticParams(params: Map<String, Any?>) = apply { this.staticParams = params }

        /**
         * 网络请求线程池，如未设置，会使用内置的线程池[Executors.IO]
         */
        fun executor(executor: Executor): Builder = apply {
            if (this.executor != null) {
                throw IllegalArgumentException("io executor has been initialized, don't set repeatedly.")
            }
            this.executor = executor
        }

        /**
         * 刷新周边信息的时间间隔
         * @param duration 时长
         * @param unit 时间单位
         */
        fun durationForTriggerRefresh(duration: Long, unit: TimeUnit = TimeUnit.SECONDS) = apply { this.durationForTriggerRefresh = unit.toMillis(duration) }

        /**
         * @param distance 超过此距离会触发刷新周边道路信息，单位为米
         */
        fun distanceForTriggerRefresh(distance: Float) = apply { this.distanceForTriggerRefresh = distance }

        /**
         * 云平台配置信息,此参数为必选项，不设置会抛异常
         * @param config 云平台配置
         */
        fun aiCloudConfig(config: MoGoAiCloudClientConfig) = apply { this.aiCloudConfig = config }

        /**
         * 云平台baseUrl
         * @param baseUrl 云平台baseUrl
         */
        fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl }

        fun build() : V2XConfig = V2XConfig(this)
    }
}