/*
 * SPDX-FileCopyrightText: Sebastiano Barezzi
 * SPDX-License-Identifier: Apache-2.0
 */

package com.xyzshell.andinfo.libs.cpu.models

/**
 * `struct cpuinfo_cluster`
 * CPU核心集群信息结构体（big.LITTLE架构中的大核小核集群）
 */
data class Cluster(
    /**
     * Index of the first logical processor in the cluster
     * 集群中第一个逻辑处理器的索引
     */
    val processorStart: UInt,

    /**
     * Number of logical processors in the cluster
     * 集群中的逻辑处理器数量
     */
    val processorCount: UInt,

    /**
     * Index of the first core in the cluster
     * 集群中第一个核心的索引
     */
    val coreStart: UInt,

    /**
     * Number of cores on the cluster
     * 集群中的核心数量
     */
    val coreCount: UInt,

    /**
     * Cluster ID within a package
     * 封装内的集群ID
     */
    val clusterId: UInt,

    /**
     * Physical package containing the cluster
     * 包含此集群的物理封装
     */
    val cpuPackage: Package,

    /**
     * CPU microarchitecture vendor of the cores in the cluster
     * 集群中核心的CPU微架构供应商
     */
    val vendor: Vendor,

    /**
     * CPU microarchitecture of the cores in the cluster
     * 集群中核心的CPU微架构
     */
    val uarch: Uarch,

    /**
     * x86 only
     * 仅x86架构
     *
     * Value of CPUID leaf 1 EAX register of the cores in the cluster
     * 集群中核心的CPUID leaf 1 EAX寄存器值
     */
    val cpuid: UInt?,

    /**
     * ARM and ARM64 only
     * 仅ARM和ARM64架构
     *
     * Value of Main ID Register (MIDR) of the cores in the cluster
     * 集群中核心的主ID寄存器（MIDR）值
     */
    val midr: Midr?,

    /**
     * Clock rate (non-Turbo) of the cores in the cluster, in Hz
     * 集群中核心的时钟频率（非睿频），单位赫兹（Hz）
     */
    val frequency: ULong,
) {
    companion object {
        @JvmStatic
        fun fromCpuInfo(
            processorStart: Int,
            processorCount: Int,
            coreStart: Int,
            coreCount: Int,
            clusterId: Int,
            cpuPackage: Package,
            vendor: Int,
            uarch: Int,
            cpuid: Int,
            midr: Int,
            frequency: Long,
        ) = Cluster(
            processorStart.toUInt(),
            processorCount.toUInt(),
            coreStart.toUInt(),
            coreCount.toUInt(),
            clusterId.toUInt(),
            cpuPackage,
            Vendor.fromCpuInfo(vendor),
            Uarch.fromCpuInfo(uarch),
            cpuid.takeUnless { it == 0 }?.toUInt(),
            midr.takeUnless { it == 0 }?.let { Midr.fromCpuInfo(it) },
            frequency.toULong(),
        )
    }
}
