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

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

import okio.FileSystem
import okio.Path
import okio.Path.Companion.toPath

/**
 * Linux CPU information from sysfs
 * 从sysfs获取的Linux CPU信息
 */
data class LinuxCpu(
    /**
     * CPU ID (0-based)
     * CPU编号（从0开始）
     */
    val id: Int,
) {
    private val cpuBaseDir = CPUINFO_BASE_DIR / "cpu${id}"

    init {
        require(FILESYSTEM.exists(cpuBaseDir)) { "CPU $id doesn't exist" }
    }

    /**
     * Whether this CPU is online
     * 此CPU是否在线
     */
    val isOnline: Boolean?
        get() = getIntArray(ONLINE_CPUS)?.contains(id)

    /**
     * Current frequency, in Hz.
     * 当前频率，单位赫兹（Hz）
     */
    val currentFrequencyHz: Long?
        get() = getLong(cpuBaseDir / CPUINFO_CURRENT_FREQ)?.let { it * 1000 }

    /**
     * Minimum frequency, in Hz.
     * 最小频率，单位赫兹（Hz）
     */
    val minimumFrequencyHz: Long?
        get() = getLong(cpuBaseDir / CPUINFO_MINIMUM_FREQ)?.let { it * 1000 }

    /**
     * Maximum frequency, in Hz.
     * 最大频率，单位赫兹（Hz）
     */
    val maximumFrequencyHz: Long?
        get() = getLong(cpuBaseDir / CPUINFO_MAXIMUM_FREQ)?.let { it * 1000 }

    /**
     * Current frequency, in Hz.
     * 当前频率（调频器），单位赫兹（Hz）
     */
    val scalingCurrentFrequencyHz: Long?
        get() = getLong(cpuBaseDir / SCALING_CURRENT_FREQ)?.let { it * 1000 }

    /**
     * Minimum frequency, in Hz.
     * 最小频率（调频器），单位赫兹（Hz）
     */
    val scalingMinimumFrequencyHz: Long?
        get() = getLong(cpuBaseDir / SCALING_MINIMUM_FREQ)?.let { it * 1000 }

    /**
     * Maximum frequency, in Hz.
     * 最大频率（调频器），单位赫兹（Hz）
     */
    val scalingMaximumFrequencyHz: Long?
        get() = getLong(cpuBaseDir / SCALING_MAXIMUM_FREQ)?.let { it * 1000 }

    // File utils
    // 文件工具方法

    /**
     * Read a string from a sysfs file
     * 从sysfs文件读取字符串
     */
    private fun getString(path: Path) = runCatching {
        FILESYSTEM.read(path) {
            readUtf8Line()
        }
    }.getOrNull()

    /**
     * Read a long value from a sysfs file
     * 从sysfs文件读取长整型值
     */
    private fun getLong(path: Path) = getString(path)?.toLongOrNull()

    /**
     * Parse CPU list from sysfs (e.g., "0-3,5,7-9" -> [0,1,2,3,5,7,8,9])
     * 从sysfs解析CPU列表（例如，"0-3,5,7-9" -> [0,1,2,3,5,7,8,9]）
     */
    private fun getIntArray(path: Path) = getString(path)?.let {
        mutableListOf<Int>().apply {
            for (item in it.split(",")) {
                val values = item.split('-')
                assert(values.size <= 2)

                if (values.size == 1) {
                    add(values.first().toInt())
                } else if (values.size == 2) {
                    for (i in values[0].toInt()..values[1].toInt()) {
                        add(i)
                    }
                }
            }
        }.toTypedArray()
    }

    companion object {
        /**
         * Base directory for CPU information in sysfs
         * sysfs中CPU信息的基础目录
         */
        val CPUINFO_BASE_DIR = "/sys/devices/system/cpu".toPath()

        private val FILESYSTEM = FileSystem.SYSTEM

        private val ONLINE_CPUS = CPUINFO_BASE_DIR / "online"

        private const val CPUINFO_CURRENT_FREQ = "cpufreq/cpuinfo_cur_freq"
        private const val CPUINFO_MINIMUM_FREQ = "cpufreq/cpuinfo_min_freq"
        private const val CPUINFO_MAXIMUM_FREQ = "cpufreq/cpuinfo_max_freq"

        private const val SCALING_CURRENT_FREQ = "cpufreq/scaling_cur_freq"
        private const val SCALING_MINIMUM_FREQ = "cpufreq/scaling_min_freq"
        private const val SCALING_MAXIMUM_FREQ = "cpufreq/scaling_max_freq"

        /**
         * Create LinuxCpu from Processor
         * 从Processor创建LinuxCpu
         */
        fun fromProcessor(processor: Processor) = LinuxCpu(processor.linuxId.toInt())
    }
}
