package com.doverfuelingsolutions.issp.driver.lib

import com.doverfuelingsolutions.issp.driver.scan.ComScanKeyManager
import com.doverfuelingsolutions.issp.driver.scan.ScanValueListener
import com.doverfuelingsolutions.issp.utils.thread.ThreadUtil
import com.doverfuelingsolutions.issp.utils.log.DFSLog
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

class ScanCodeManager : ScanValueListener {

    private lateinit var comScanKeyManager: ComScanKeyManager
    val isAvailable: Boolean get() = isInit
    private var isInit = false

    private var callback: ((v: String?) -> Unit)? = null

    override fun onScanValue(value: String?) {
        DFSLog.d("scan code: $value")
        callback?.invoke(value)
        callback = null
    }

    suspend fun start() = suspendCoroutine<String?> {
        ThreadUtil.io {
            if (!isInit) {
                it.resume(null)
                return@io
            }

            comScanKeyManager.start()
            callback = { v -> it.resume(v) }
        }
    }

    fun stop() {
        ThreadUtil.io {
            comScanKeyManager.stop()
        }
    }

    suspend fun create() = suspendCoroutine<Boolean> {
        if (isInit) {
            it.resume(true)
            return@suspendCoroutine
        }

        ThreadUtil.io {
            try {
                comScanKeyManager = ComScanKeyManager("/dev/ttyACM0", 115200, this)
                isInit = true
            } catch (e: Exception) {
                DFSLog.e(e)
                isInit = false
            }
            it.resume(isInit)
        }
    }

    fun destroy() {
        isInit = false
        ThreadUtil.io {
            comScanKeyManager.stop()
            comScanKeyManager.destroy()
        }
    }
}