#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# Example output:
# <<<lnx_cpuinfo:sep(58)>>>
# processor:0
# vendor_id:GenuineIntel
# cpu family:6
# model:45
# model name:Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz
# stepping:7
# microcode:0x70c
# cpu MHz:1200.000
# cache size:12288 KB
# physical id:0
# siblings:12
# core id:0
# cpu cores:6
# apicid:0
# initial apicid:0
# fpu:yes
# fpu_exception:yes
# cpuid level:13
# wp:yes
# bogomips:6399.88
# clflush size:64
# cache_alignment:64
# address sizes:46 bits physical, 48 bits virtual
# power management:
#
# processor:1
# ...


# Note: This node is also being filled by dmidecode
def inv_lnx_cpuinfo(info):
    node = inv_tree("hardware.cpu.")
    num_threads_total = 0
    sockets = set([])
    for varname, value in info:
        if varname == "cpu cores":
            node["cores_per_cpu"] = int(value)
        elif varname == "siblings":
            node["threads_per_cpu"] = int(value)
        elif varname == "vendor_id":
            node["vendor"] = {
                "GenuineIntel": "intel",
                "AuthenticAMD": "amd",
            }.get(value, value)
        elif varname == "cache size":
            node["cache_size"] = int(value.split()[0]) * 1024  # everything is normalized to bytes!
        elif varname == "model name":
            node["model"] = value
        # For the following two entries we assume that all
        # entries are numbered in increasing order in /proc/cpuinfo.
        elif varname == "processor":
            num_threads_total = int(value) + 1
        elif varname == "physical id":
            sockets.add(int(value))
        elif varname == "flags":
            if re.search(" lm ", value):
                node["arch"] = "x86_64"
            else:
                node["arch"] = "i386"

    num_sockets = len(sockets)

    if num_threads_total:
        node.setdefault("cores_per_cpu", 1)
        node.setdefault("threads_per_cpu", 1)
        node["cores"] = num_sockets * node["cores_per_cpu"]
        node["threads"] = num_sockets * node["threads_per_cpu"]
        node["cpus"] = num_sockets


inv_info["lnx_cpuinfo"] = {
    "inv_function": inv_lnx_cpuinfo,
}
