package com.xyzshell.andinfo.libs

import android.content.Context
import com.xyzshell.andinfo.libs.gpu.models.EglInformation
import com.xyzshell.andinfo.libs.gpu.models.GlInformation
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDevice
import com.xyzshell.andinfo.libs.gpu.models.VkPhysicalDeviceType
import com.xyzshell.andinfo.libs.gpu.models.VkVendorId
import com.xyzshell.andinfo.libs.gpu.utils.EglUtils
import com.xyzshell.andinfo.libs.gpu.utils.VkUtils

/**
 * GPU（图形处理器）信息工具类
 * 提供 Vulkan 和 OpenGL ES 的详细硬件信息
 * 包括供应商、型号、显存、API版本、扩展等
 */
class GpuInfo(private val context: Context) {

    init {
        // 加载本地库以获取 Vulkan 和 EGL 信息
        System.loadLibrary("andinfo")
    }

    /**
     * 获取完整的 GPU 信息
     * 包括 Vulkan 物理设备信息和 EGL 信息
     * @return GpuInformationData GPU信息数据
     */
    fun getGpuInformation(): GpuInformationData {
        val vkPhysicalDevices = VkUtils.getVkInfo()
        val eglInformation = EglUtils.getEglInformation()
        return GpuInformationData(vkPhysicalDevices, eglInformation)
    }

    /**
     * 获取 Vulkan 是否支持
     * @return 是否支持 Vulkan API
     */
    fun isVulkanSupported(): Boolean {
        return try {
            val devices = VkUtils.getVkInfo()
            devices != null && devices.isNotEmpty()
        } catch (e: Exception) {
            false
        }
    }

    /**
     * 获取主 GPU 供应商名称
     * 优先从 Vulkan 获取，如果不可用则从 OpenGL ES 获取
     * @return GPU 供应商名称（如 "ARM", "Qualcomm", "Mali" 等）
     */
    fun getVendorName(): String? {
        val gpuInfo = getGpuInformation()

        // 优先使用 Vulkan 信息
        gpuInfo.vkPhysicalDevices?.firstOrNull()?.let { device ->
            return getVendorNameFromId(device.vendorId)
                ?: device.registeredVendorId?.let { getVendorName(it) }
        }

        // 回退到 OpenGL ES 信息
        return gpuInfo.eglInformation?.glInformation?.glVendor
    }

    /**
     * 获取主 GPU 型号/渲染器名称
     * 优先从 Vulkan 获取，如果不可用则从 OpenGL ES 获取
     * @return GPU 型号名称（如 "Adreno 650", "Mali-G78" 等）
     */
    fun getRendererName(): String? {
        val gpuInfo = getGpuInformation()

        // 优先使用 Vulkan 设备名称
        gpuInfo.vkPhysicalDevices?.firstOrNull()?.let { device ->
            return device.deviceName
        }

        // 回退到 OpenGL ES 渲染器信息
        return gpuInfo.eglInformation?.glInformation?.glRenderer
    }

    /**
     * 获取 Vulkan API 版本信息
     * @return Vulkan API 版本字符串（如 "1.3.0"），如果不支持则返回 null
     */
    fun getVulkanApiVersion(): String? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.vkPhysicalDevices?.firstOrNull()?.let { device ->
            val version = device.apiVersion
            "${version.major}.${version.minor}.${version.patch}"
        }
    }

    /**
     * 获取 Vulkan 驱动版本
     * @return 驱动版本号
     */
    fun getVulkanDriverVersion(): Long? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.vkPhysicalDevices?.firstOrNull()?.driverVersion
    }

    /**
     * 获取 OpenGL ES 版本
     * @return OpenGL ES 版本字符串（如 "OpenGL ES 3.2"）
     */
    fun getOpenGLVersion(): String? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.eglInformation?.glInformation?.glVersion
    }

    /**
     * 获取 EGL 版本
     * @return EGL 版本字符串
     */
    fun getEglVersion(): String? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.eglInformation?.eglVersion
    }

    /**
     * 获取 OpenGL ES 扩展列表
     * @return OpenGL ES 扩展字符串
     */
    fun getOpenGLExtensions(): String? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.eglInformation?.glInformation?.glExtensions
    }

    /**
     * 获取 OpenGL ES 扩展数量
     * @return 扩展数量
     */
    fun getOpenGLExtensionCount(): Int {
        return getOpenGLExtensions()?.split(" ")?.filter { it.isNotEmpty() }?.size ?: 0
    }

    /**
     * 获取 EGL 扩展列表
     * @return EGL 扩展列表
     */
    fun getEglExtensions(): List<String>? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.eglInformation?.eglExtensions
    }

    /**
     * 获取 EGL 扩展数量
     * @return 扩展数量
     */
    fun getEglExtensionCount(): Int {
        return getEglExtensions()?.size ?: 0
    }

    /**
     * 获取 EGL 支持的客户端 API
     * @return 客户端 API 列表（如 ["OpenGL_ES"]）
     */
    fun getEglClientApis(): List<String>? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.eglInformation?.eglClientApi
    }

    /**
     * 获取 GPU 设备类型
     * @return 设备类型（集成显卡、独立显卡等）
     */
    fun getDeviceType(): VkPhysicalDeviceType? {
        val gpuInfo = getGpuInformation()
        return gpuInfo.vkPhysicalDevices?.firstOrNull()?.deviceType
    }

    /**
     * 获取 GPU 设备类型的中文描述
     * @return 设备类型中文描述
     */
    fun getDeviceTypeDescription(): String? {
        return getDeviceType()?.let {
            vkPhysicalDeviceTypeToStringChinese[it.value]
        }
    }

    /**
     * 获取格式化的 GPU 信息摘要
     * @return 格式化的文本信息
     */
    fun getGpuSummary(): String {
        val sb = StringBuilder()
        val gpuInfo = getGpuInformation()

        sb.append("=== GPU 基本信息 ===\n")
        getVendorName()?.let { sb.append("供应商: $it\n") }
        getRendererName()?.let { sb.append("型号: $it\n") }
        getDeviceTypeDescription()?.let { sb.append("类型: $it\n") }

        // Vulkan 信息
        if (isVulkanSupported()) {
            sb.append("\n=== Vulkan 信息 ===\n")
            sb.append("支持: 是\n")
            getVulkanApiVersion()?.let { sb.append("API 版本: $it\n") }
            getVulkanDriverVersion()?.let { sb.append("驱动版本: $it\n") }

            gpuInfo.vkPhysicalDevices?.forEach { device ->
                sb.append("\n--- Vulkan 设备 ---\n")
                sb.append("设备名称: ${device.deviceName}\n")
                sb.append("设备 ID: ${device.deviceId}\n")
                sb.append("供应商 ID: 0x${device.vendorId.toString(16)}\n")
                device.registeredVendorId?.let {
                    sb.append("注册供应商: ${getVendorName(it)}\n")
                }
                sb.append("设备类型: ${vkPhysicalDeviceTypeToStringChinese[device.deviceType.value]}\n")
                val ver = device.apiVersion
                sb.append("API 版本: ${ver.major}.${ver.minor}.${ver.patch}")
                if (ver.variant > 0) {
                    sb.append(" (变体: ${ver.variant})")
                }
                sb.append("\n")
            }
        } else {
            sb.append("\n=== Vulkan 信息 ===\n")
            sb.append("支持: 否\n")
        }

        // OpenGL ES 信息
        sb.append("\n=== OpenGL ES 信息 ===\n")
        gpuInfo.eglInformation?.glInformation?.let { gl ->
            gl.glVendor?.let { sb.append("供应商: $it\n") }
            gl.glRenderer?.let { sb.append("渲染器: $it\n") }
            gl.glVersion?.let { sb.append("版本: $it\n") }
            val extCount = getOpenGLExtensionCount()
            sb.append("扩展数量: $extCount\n")
        }

        // EGL 信息
        sb.append("\n=== EGL 信息 ===\n")
        gpuInfo.eglInformation?.let { egl ->
            egl.eglVendor?.let { sb.append("供应商: $it\n") }
            egl.eglVersion?.let { sb.append("版本: $it\n") }
            egl.eglClientApi?.let { apis ->
                sb.append("客户端 API: ${apis.joinToString(", ")}\n")
            }
            val extCount = getEglExtensionCount()
            sb.append("扩展数量: $extCount\n")
        }

        return sb.toString()
    }

    /**
     * 根据供应商 ID 获取供应商名称
     * 使用 PCI 供应商 ID 标准
     */
    private fun getVendorNameFromId(vendorId: Long): String? {
        return when (vendorId) {
            0x1002L -> "AMD"
            0x1010L -> "ImgTec"
            0x10DEL -> "NVIDIA"
            0x13B5L -> "ARM"
            0x5143L -> "Qualcomm"
            0x8086L -> "Intel"
            0x10001L -> "Vivante"
            0x10002L -> "VeriSilicon"
            0x10003L -> "Kazan"
            0x10004L -> "Codeplay"
            0x10005L -> "Mesa"
            0x10006L -> "POCL"
            0x10007L -> "Mobileye"
            else -> null
        }
    }

    /**
     * 从注册的 Vulkan 供应商 ID 获取名称
     */
    private fun getVendorName(vendorId: VkVendorId): String {
        return vkVendorIdToStringChinese[vendorId] ?: vkVendorIdToString[vendorId] ?: "Unknown"
    }

    /**
     * GPU 信息数据类
     * @property vkPhysicalDevices Vulkan 物理设备列表
     * @property eglInformation EGL 信息
     */
    data class GpuInformationData(
        val vkPhysicalDevices: List<VkPhysicalDevice>?,  // Vulkan 物理设备列表
        val eglInformation: EglInformation?               // EGL 信息（包含 OpenGL ES 信息）
    )

    companion object {
        /**
         * Vulkan 物理设备类型映射（英文）
         */
        val vkPhysicalDeviceTypeToString = mapOf(
            VkPhysicalDeviceType.OTHER.value to "Other",
            VkPhysicalDeviceType.INTEGRATED_GPU.value to "Integrated GPU",
            VkPhysicalDeviceType.DISCRETE_GPU.value to "Discrete GPU",
            VkPhysicalDeviceType.VIRTUAL_GPU.value to "Virtual GPU",
            VkPhysicalDeviceType.CPU.value to "CPU",
        )

        /**
         * Vulkan 物理设备类型映射（中文）
         */
        val vkPhysicalDeviceTypeToStringChinese = mapOf(
            VkPhysicalDeviceType.OTHER.value to "其他",
            VkPhysicalDeviceType.INTEGRATED_GPU.value to "集成显卡",
            VkPhysicalDeviceType.DISCRETE_GPU.value to "独立显卡",
            VkPhysicalDeviceType.VIRTUAL_GPU.value to "虚拟显卡",
            VkPhysicalDeviceType.CPU.value to "CPU",
        )

        /**
         * Vulkan 注册供应商 ID 映射（英文）
         */
        val vkVendorIdToString = mapOf(
            VkVendorId.KHRONOS to "Khronos",
            VkVendorId.VIV to "Vivante",
            VkVendorId.VSI to "VeriSilicon",
            VkVendorId.KAZAN to "Kazan",
            VkVendorId.CODEPLAY to "Codeplay",
            VkVendorId.MESA to "Mesa",
            VkVendorId.POCL to "POCL",
            VkVendorId.MOBILEYE to "Mobileye",
        )

        /**
         * Vulkan 注册供应商 ID 映射（中文）
         */
        val vkVendorIdToStringChinese = mapOf(
            VkVendorId.KHRONOS to "Khronos（科纳斯）",
            VkVendorId.VIV to "Vivante（维万特）",
            VkVendorId.VSI to "VeriSilicon（芯原）",
            VkVendorId.KAZAN to "Kazan",
            VkVendorId.CODEPLAY to "Codeplay",
            VkVendorId.MESA to "Mesa",
            VkVendorId.POCL to "POCL",
            VkVendorId.MOBILEYE to "Mobileye（移动眼）",
        )

        /**
         * PCI 供应商 ID 到名称映射
         * 常见的 GPU 供应商标准 PCI ID
         */
        val pciVendorIdToString = mapOf(
            0x1002L to "AMD",
            0x1010L to "ImgTec",
            0x10DEL to "NVIDIA",
            0x13B5L to "ARM",
            0x5143L to "Qualcomm",
            0x8086L to "Intel",
        )
    }
}


