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

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

/**
 * `struct cpuinfo_core`
 * CPU核心信息结构体
 */
data class Core(
    /**
     * Index of the first logical processor on this core.
     * 此核心上第一个逻辑处理器的索引
     */
    val processorStart: UInt,

    /**
     * Number of logical processors on this core
     * 此核心上的逻辑处理器数量
     */
    val processorCount: UInt,

    /**
     * Core ID within a package
     * 核心在封装内的ID
     */
    val coreId: UInt,

    /**
     * Cluster containing this core
     * 包含此核心的集群
     */
    val cluster: Cluster,

    /**
     * Physical package containing this core.
     * 包含此核心的物理封装
     */
    val cpuPackage: Package,

    /**
     * Vendor of the CPU microarchitecture for this core
     * 此核心的CPU微架构供应商
     */
    val vendor: Vendor,

    /**
     * CPU microarchitecture for this core
     * 此核心的CPU微架构
     */
    val uarch: Uarch,

    /**
     * x86 only
     * 仅x86架构
     *
     * Value of CPUID leaf 1 EAX register for this core
     * 此核心的CPUID leaf 1 EAX寄存器值
     */
    val cpuid: UInt?,

    /**
     * ARM and ARM64 only
     * 仅ARM和ARM64架构
     *
     * Value of Main ID Register (MIDR) for this core
     * 此核心的主ID寄存器（MIDR）值
     */
    val midr: Midr?,

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