package cn.i2edu.speech_plugin.util

import android.content.Context
import android.util.Log
import cn.i2edu.speech_plugin.audioUtils.audiotransfer.DecodeEngine
import cn.i2edu.speech_plugin.audioUtils.audiotransfer.DecodeOperateInterface
import com.tencent.taisdk.*
import com.tencent.taisdk.TAIErrCode.SUCC
import java.io.File
import java.io.FileInputStream
import com.tencent.taisdk.TAIOralEvaluationFileType
import com.tencent.taisdk.TAIOralEvaluationServerType
import com.tencent.taisdk.TAIOralEvaluationStorageMode
import com.tencent.taisdk.TAIOralEvaluationEvalMode
import com.tencent.taisdk.TAIOralEvaluationWorkMode
import com.tencent.taisdk.TAIOralEvaluationParam
import java.util.*
import android.system.Os.close
import java.io.InputStream
import android.system.Os.close
import java.io.IOException

interface SmartOralEvaluatorCallBack {
    fun onResult(result: TAIOralEvaluationRet?)
    fun onError(message: String)
}

class SmartOralAudioEvaluatorUtil private constructor(val context: Context) {
    private var smartOralEvaluatorCallBack: SmartOralEvaluatorCallBack? = null
    private var oral: TAIOralEvaluation? = null
    private val TAG: String = "SmartOralAudioEvaluator"

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

        fun getInstance(context: Context) = instance
                ?: synchronized(this) {
                    instance
                            ?: SmartOralAudioEvaluatorUtil(context)
                                    .also {
                                    }
                                    .also { instance = it }
                }
    }

    fun startEvaluator(en: String, filePath: String, decodedFilePath: String) {
        oral = TAIOralEvaluation()
        oral?.setListener(object: TAIOralEvaluationListener {
            override fun onVolumeChanged(p0: Int) {
            }

            override fun onEvaluationData(p0: TAIOralEvaluationData?, p1: TAIOralEvaluationRet?, p2: TAIError?) {
                if (p0?.bEnd == true && p2?.code == SUCC) {
                    Log.d(TAG, "result: ${p1?.pronFluency}, ${p1?.pronCompletion}, ${p1?.pronAccuracy}")
                    smartOralEvaluatorCallBack?.onResult(p1)
                } else {
                    Log.e(TAG, "error code: ${p2?.code} message: ${p2?.desc}")
                    smartOralEvaluatorCallBack?.onError(p2?.desc ?: "")
                }
            }

            override fun onEndOfSpeech() {
            }
        })
        val param = TAIOralEvaluationParam()
        param.context = context
        param.appId = "1301049120"
        param.secretId = "AKIDUf0EEzc8NMpPmu4Po1zhXBZicKp5G7xZ"
        param.secretKey = "WnsjKaqtgDVbV9cMtABwVptarwpWyBAt"
        param.sessionId = UUID.randomUUID().toString()
        param.workMode = TAIOralEvaluationWorkMode.ONCE
        param.evalMode = TAIOralEvaluationEvalMode.SENTENCE
        param.storageMode = TAIOralEvaluationStorageMode.DISABLE
        param.serverType = TAIOralEvaluationServerType.ENGLISH
        param.fileType = TAIOralEvaluationFileType.WAV// 只支持mp3
        param.soeAppId = "soe_1002252"
        param.scoreCoeff = 1.0
        param.refText = en
        Thread {
            DecodeEngine.getInstance(context).beginDecodeMusicFile(filePath, decodedFilePath, 0, 16000, 1, 2, object : DecodeOperateInterface {
                override fun updateDecodeProgress(decodeProgress: Int) {
                }

                override fun decodeSuccess() {
                    try {

                        val file = File(decodedFilePath)
                        val bytes: ByteArray = file.readBytes()

                        val data = TAIOralEvaluationData()
                        data.seqId = 1
                        data.bEnd = true
                        data.audio = bytes
                        oral?.oralEvaluation(param, data, TAIOralEvaluationCallback {
                            //接口调用结果返回
                            Log.d(TAG, "oralEvaluation call result: ${it?.code ?: "error null"}")
                        })
                        file.delete()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        smartOralEvaluatorCallBack?.onError("failed ${e.message}")
                    }
                }

                override fun decodeFail() {
                    smartOralEvaluatorCallBack?.onError("decode fail")
                }
            })
        }.start()
    }

    fun setEvaluatorCallBack(callback: SmartOralEvaluatorCallBack): SmartOralAudioEvaluatorUtil? {
        this.smartOralEvaluatorCallBack = callback
        return instance
    }
}