package cn.learningpad.oraltrainer.sdk

import android.content.Context
import java.util.concurrent.CopyOnWriteArrayList

class OralTrainerSdk private constructor(
    context: Context,
    val config: OralTrainerSdkConfig,
) {
    private val appContext = context.applicationContext

    val cache: OralTrainerCache = OralTrainerCache(appContext, config)
    val sentenceBoundaryApi: SentenceBoundaryApi = SentenceBoundaryApi(appContext, config)
    val userApi: UserApi = UserApi(appContext, config)
    val videoCatalogApi: VideoCatalogApi = VideoCatalogApi(appContext, config)
    private val remoteAssessors = CopyOnWriteArrayList<RemoteImitationQualityAssessor>()

    fun createRemoteImitationQualityAssessor(): RemoteImitationQualityAssessor {
        return RemoteImitationQualityAssessor(appContext, config).also(remoteAssessors::add)
    }

    @JvmOverloads
    fun createController(
        playerConfig: PlayerConfig = PlayerConfig(),
        imitationAssessor: ImitationQualityAssessor = NoopImitationQualityAssessor,
    ): OralTrainerController {
        return OralTrainerController(
            context = appContext,
            sdkConfig = config,
            initialConfig = playerConfig,
            imitationAssessor = imitationAssessor,
        )
    }

    fun release() {
        sentenceBoundaryApi.release()
        videoCatalogApi.release()
        remoteAssessors.forEach { it.release() }
        remoteAssessors.clear()
        StreamingCache.release()
    }

    companion object {
        @Volatile
        private var instance: OralTrainerSdk? = null

        @JvmStatic
        @JvmOverloads
        fun init(
            context: Context,
            config: OralTrainerSdkConfig = OralTrainerSdkConfig(),
        ): OralTrainerSdk {
            return synchronized(this) {
                instance ?: OralTrainerSdk(context.applicationContext, config).also {
                    instance = it
                }
            }
        }

        @JvmStatic
        fun get(): OralTrainerSdk {
            return instance ?: error("Call OralTrainerSdk.init(context) before using the SDK.")
        }
    }
}
