package com.brentvatne.react

import android.media.MediaCodecList
import android.media.MediaDrm
import android.media.MediaFormat
import android.media.UnsupportedSchemeException
import android.os.Build
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import java.util.UUID

class VideoDecoderInfoModule(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {
    override fun getName(): String = REACT_CLASS

    @ReactMethod
    fun getWidevineLevel(p: Promise) {
        var widevineLevel = 0
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            p.resolve(widevineLevel)
            return
        }
        try {
            val mediaDrm = MediaDrm(WIDEVINE_UUID)
            val securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY)
            widevineLevel = when (securityProperty) {
                "L1" -> 1
                "L2" -> 2
                "L3" -> 3
                else -> 0
            }
        } catch (e: UnsupportedSchemeException) {
            e.printStackTrace()
        }
        p.resolve(widevineLevel)
    }

    @ReactMethod
    fun isCodecSupported(mimeType: String?, width: Double, height: Double, p: Promise?) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            p?.resolve("unsupported")
            return
        }
        val mRegularCodecs = MediaCodecList(MediaCodecList.REGULAR_CODECS)
        val format = MediaFormat.createVideoFormat(mimeType!!, width.toInt(), height.toInt())
        val codecName = mRegularCodecs.findDecoderForFormat(format)
        if (codecName == null) {
            p?.resolve("unsupported")
            return
        }

        // Fallback for android < 10
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            p?.resolve("software")
            return
        }
        val isHardwareAccelerated = mRegularCodecs.codecInfos.any {
            it.name.equals(codecName, ignoreCase = true) && it.isHardwareAccelerated
        }
        p?.resolve(if (isHardwareAccelerated) "software" else "hardware")
    }

    @ReactMethod
    fun isHEVCSupported(p: Promise) = isCodecSupported("video/hevc", 1920.0, 1080.0, p)

    companion object {
        private val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
        private const val SECURITY_LEVEL_PROPERTY = "securityLevel"
        private const val REACT_CLASS = "VideoDecoderInfoModule"
    }
}
