package com.dtourolle.jellytau.player

import android.media.MediaCodecList
import android.util.Log

/**
 * Detects hardware codec capabilities using MediaCodecList.
 *
 * This class queries the device's media codec capabilities and reports
 * them to the Rust backend via JNI for accurate DeviceProfile generation.
 */
object CodecDetector {
    private const val TAG = "CodecDetector"

    /**
     * Data class to hold detected codec capabilities.
     */
    data class CodecCapabilities(
        val videoCodecs: List<String>,
        val audioCodecs: List<String>
    )

    /**
     * Detect all hardware decoders available on this device.
     *
     * Uses Android's MediaCodecList API to query supported MIME types
     * and maps them to Jellyfin codec names.
     *
     * @return CodecCapabilities containing lists of supported video and audio codecs
     */
    fun detectHardwareCodecs(): CodecCapabilities {
        val videoCodecs = mutableSetOf<String>()
        val audioCodecs = mutableSetOf<String>()

        try {
            // Get all codec infos (including both hardware and software codecs)
            val codecList = MediaCodecList(MediaCodecList.ALL_CODECS)

            for (codecInfo in codecList.codecInfos) {
                // Only interested in decoders (not encoders)
                if (codecInfo.isEncoder) continue

                // Check if it's a hardware codec
                val isHardware = !codecInfo.isSoftwareOnly

                for (type in codecInfo.supportedTypes) {
                    when {
                        type.startsWith("video/") -> {
                            val codec = mapMimeTypeToCodecName(type, isVideo = true)
                            if (codec != null) {
                                videoCodecs.add(codec)
                                Log.d(TAG, "Video codec: $codec (MIME: $type, Hardware: $isHardware)")
                            }
                        }
                        type.startsWith("audio/") -> {
                            val codec = mapMimeTypeToCodecName(type, isVideo = false)
                            if (codec != null) {
                                audioCodecs.add(codec)
                                Log.d(TAG, "Audio codec: $codec (MIME: $type, Hardware: $isHardware)")
                            }
                        }
                    }
                }
            }

            Log.i(TAG, "Detected ${videoCodecs.size} video codecs: ${videoCodecs.sorted()}")
            Log.i(TAG, "Detected ${audioCodecs.size} audio codecs: ${audioCodecs.sorted()}")
        } catch (e: Exception) {
            Log.e(TAG, "Error detecting codecs", e)
        }

        return CodecCapabilities(
            videoCodecs = videoCodecs.sorted(),
            audioCodecs = audioCodecs.sorted()
        )
    }

    /**
     * Map Android MIME types to Jellyfin codec names.
     *
     * Based on Jellyfin's codec naming conventions and Android's
     * supported MIME type constants.
     *
     * @param mimeType Android MIME type (e.g., "video/avc", "audio/mp4a-latm")
     * @param isVideo Whether this is a video codec
     * @return Jellyfin codec name or null if unknown
     */
    private fun mapMimeTypeToCodecName(mimeType: String, isVideo: Boolean): String? {
        return when (mimeType) {
            // Video codecs
            "video/avc" -> "h264"
            "video/hevc" -> "hevc"
            "video/x-vnd.on2.vp8" -> "vp8"
            "video/x-vnd.on2.vp9" -> "vp9"
            "video/av01" -> "av1"
            "video/mp4v-es" -> "mpeg4"
            "video/3gpp" -> "h263"
            "video/mpeg2" -> "mpeg2video"
            "video/divx" -> "divx"
            "video/xvid" -> "xvid"
            "video/x-ms-wmv" -> "wmv"
            "video/vc1" -> "vc1"

            // Audio codecs
            "audio/mp4a-latm" -> "aac"
            "audio/mpeg" -> "mp3"
            "audio/mpeg-L1" -> "mp1"
            "audio/mpeg-L2" -> "mp2"
            "audio/opus" -> "opus"
            "audio/vorbis" -> "vorbis"
            "audio/flac" -> "flac"
            "audio/alac" -> "alac"
            "audio/ac3" -> "ac3"
            "audio/eac3" -> "eac3"
            "audio/eac3-joc" -> "eac3"
            "audio/dts" -> "dts"
            "audio/vnd.dts.hd" -> "dts"
            "audio/x-ms-wma" -> "wma"
            "audio/amr-nb" -> "amrnb"
            "audio/amr-wb" -> "amrwb"
            "audio/3gpp" -> "amrnb"
            "audio/raw" -> "pcm"

            else -> {
                Log.d(TAG, "Unknown MIME type: $mimeType")
                null
            }
        }
    }
}
