#!/usr/bin/env python3

# This tool runs on the host CPU and gathers all SST related configuration from
# the BMC (Redfish) and from the linux driver, and compares them to catch any
# errors or disagreement. Only required arguments are the details to start a
# Redfish session.
#
# This was tested running on a live Arch Linux ISO environment. Any Linux
# installation should work, but best to get the latest tools and kernel driver.
#
# Required dependencies:
# * DMTF's redfish python library. This is available in pip.
# * intel-speed-select tool from the kernel source tree
#   (tools/power/x86/intel-speed-select), and available in the PATH.

import argparse
import json
import re
import subprocess
import sys

import redfish

linux_cpu_map = dict()
success = True


def filter_powerdomains(sst_data):
    # For TPMI-based CPUs, we only care about powerdomain-0
    cpus = list(sst_data.keys())
    for proc in cpus:
        match = re.search("powerdomain-(\\d+)", proc)
        if not match or match.group(1) == "0":
            continue
        del sst_data[proc]


def get_linux_output():
    cmd = [
        "/usr/bin/env",
        "intel-speed-select",
        "--debug",
        "--format=json",
        "perf-profile",
        "info",
    ]
    process = subprocess.run(cmd, capture_output=True, text=True)
    process.check_returncode()
    result = json.loads(process.stderr)
    filter_powerdomains(result)

    global linux_cpu_map
    linux_cpu_map = dict()
    for line in process.stdout.split("\n"):
        match = re.search("logical_cpu:(\\d+).*punit_core:(\\d+)", line)
        if not match:
            continue
        logical_thread = int(match.group(1))
        physical_core = int(match.group(2))
        linux_cpu_map[logical_thread] = physical_core

    cmd = [
        "/usr/bin/env",
        "intel-speed-select",
        "--format=json",
        "perf-profile",
        "get-config-current-level",
    ]
    process = subprocess.run(cmd, capture_output=True, text=True)
    current_level = json.loads(process.stderr)
    filter_powerdomains(current_level)

    for proc, data in current_level.items():
        result[proc].update(data)

    return result


def compare(redfish_val, linux_val, description):
    err = ""
    if None in (redfish_val, linux_val):
        err = "MISSING VALUE"
    elif redfish_val != linux_val:
        err = "!! MISMATCH !!"
        global success
        success = False
    print(f"{description}: {err}")
    print(f"  Redfish: {redfish_val}")
    print(f"  Linux: {linux_val}")


def get_linux_package(linux_data, redfish_id):
    match = re.match("cpu(\\d+)", redfish_id)
    if not match:
        raise RuntimeError(f"Redfish CPU name is unexpected: {redfish_id}")
    num = match.group(1)
    matching_keys = []
    for key in linux_data.keys():
        if re.match(f"^package-{num}:.*", key):
            matching_keys.append(key)
    if len(matching_keys) != 1:
        raise RuntimeError(
            f"Unexpected number of matching linux objects for {redfish_id}"
        )
    return linux_data[matching_keys[0]]


def compare_config(redfish_config, linux_config):
    print(f"--Checking {redfish_config['Id']}--")
    compare(
        redfish_config["BaseSpeedMHz"],
        int(linux_config["base-frequency(MHz)"]),
        "Base Speed",
    )

    actual_hp_p1 = actual_lp_p1 = 0
    actual_hp_cores = set()
    for bf in redfish_config["BaseSpeedPrioritySettings"]:
        if not actual_hp_p1 or bf["BaseSpeedMHz"] > actual_hp_p1:
            actual_hp_p1 = bf["BaseSpeedMHz"]
            actual_hp_cores = set(bf["CoreIDs"])
        if not actual_lp_p1 or bf["BaseSpeedMHz"] < actual_lp_p1:
            actual_lp_p1 = bf["BaseSpeedMHz"]

    exp_hp_p1 = exp_lp_p1 = 0
    exp_hp_cores = set()
    if "speed-select-base-freq-properties" in linux_config:
        exp_bf_props = linux_config["speed-select-base-freq-properties"]
        exp_hp_p1 = int(exp_bf_props["high-priority-base-frequency(MHz)"])
        exp_hp_cores = set(
            map(
                lambda x: linux_cpu_map[x],
                map(int, exp_bf_props["high-priority-cpu-list"].split(",")),
            )
        )
        exp_lp_p1 = int(exp_bf_props["low-priority-base-frequency(MHz)"])

    compare(actual_hp_p1, exp_hp_p1, "SST-BF High Priority P1 Freq")
    compare(actual_hp_cores, exp_hp_cores, "SST-BF High Priority Core List")
    compare(actual_lp_p1, exp_lp_p1, "SST-BF Low Priority P1 Freq")

    compare(
        redfish_config["MaxJunctionTemperatureCelsius"],
        int(linux_config["tjunction-max(C)"]),
        "Junction Temperature",
    )
    # There is no equivalent value in linux for the per-level P0_1 freq.
    compare(redfish_config["MaxSpeedMHz"], None, "SSE Max Turbo Speed")
    compare(
        redfish_config["TDPWatts"],
        int(linux_config["thermal-design-power(W)"]),
        "TDP",
    )
    compare(
        redfish_config["TotalAvailableCoreCount"],
        int(linux_config["enable-cpu-count"]) // 2,
        "Enabled Core Count",
    )

    actual_turbo = [
        (x["ActiveCoreCount"], x["MaxSpeedMHz"])
        for x in redfish_config["TurboProfile"]
    ]
    linux_turbo = (
        linux_config.get("turbo-ratio-limits-sse")
        or linux_config["turbo-ratio-limits-level-0"]
    )
    exp_turbo = []
    for bucket_key in sorted(linux_turbo.keys()):
        bucket = linux_turbo[bucket_key]
        exp_turbo.append(
            (
                int(bucket["core-count"]),
                int(bucket["max-turbo-frequency(MHz)"]),
            )
        )
    compare(actual_turbo, exp_turbo, "SSE Turbo Profile")


def get_level_from_config_id(config_id):
    match = re.match("config(\\d+)", config_id)
    if not match:
        raise RuntimeError(f"Invalid config name {config_id}")
    return match.group(1)


def main():
    parser = argparse.ArgumentParser(
        description="Compare Redfish SST properties against Linux tools"
    )
    parser.add_argument("hostname")
    parser.add_argument("--username", "-u", default="root")
    parser.add_argument("--password", "-p", default="0penBmc")
    args = parser.parse_args()

    linux_data = get_linux_output()

    bmc = redfish.redfish_client(
        base_url=f"https://{args.hostname}",
        username=args.username,
        password=args.password,
    )
    bmc.login(auth="session")

    # Load the ProcessorCollection
    resp = json.loads(bmc.get("/redfish/v1/Systems/system/Processors").text)
    for proc_member in resp["Members"]:
        proc_resp = json.loads(bmc.get(proc_member["@odata.id"]).text)
        proc_id = proc_resp["Id"]
        print()
        print(f"----Checking Processor {proc_id}----")

        if proc_resp["Status"]["State"] == "Absent":
            print("Not populated")
            continue

        # Get subset of intel-speed-select data which applies to this CPU
        pkg_data = get_linux_package(linux_data, proc_id)

        # Check currently applied config
        applied_config = proc_resp["AppliedOperatingConfig"][
            "@odata.id"
        ].split("/")[-1]
        current_level = get_level_from_config_id(applied_config)
        compare(
            current_level,
            pkg_data["get-config-current_level"],
            "Applied Config",
        )

        exp_cur_level_data = pkg_data[f"perf-profile-level-{current_level}"]

        # Check whether SST-BF is enabled
        bf_enabled = proc_resp["BaseSpeedPriorityState"].lower()
        exp_bf_enabled = exp_cur_level_data["speed-select-base-freq"]
        if exp_bf_enabled == "unsupported":
            exp_bf_enabled = "disabled"
        compare(bf_enabled, exp_bf_enabled, "SST-BF Enabled?")

        # Check high speed core list
        hscores = set(proc_resp["HighSpeedCoreIDs"])
        exp_hscores = set()
        if "speed-select-base-freq-properties" in exp_cur_level_data:
            exp_hscores = exp_cur_level_data[
                "speed-select-base-freq-properties"
            ]["high-priority-cpu-list"]
            exp_hscores = set(
                [linux_cpu_map[int(x)] for x in exp_hscores.split(",")]
            )
        compare(hscores, exp_hscores, "High Speed Core List")

        # Load the OperatingConfigCollection
        resp = json.loads(
            bmc.get(proc_resp["OperatingConfigs"]["@odata.id"]).text
        )

        # Check number of available configs
        profile_keys = list(
            filter(
                lambda x: x.startswith("perf-profile-level"), pkg_data.keys()
            )
        )
        compare(
            resp["Members@odata.count"],
            int(len(profile_keys)),
            "Number of profiles",
        )

        for config_member in resp["Members"]:
            # Load each OperatingConfig and compare all its contents
            config_resp = json.loads(bmc.get(config_member["@odata.id"]).text)
            level = get_level_from_config_id(config_resp["Id"])
            exp_level_data = pkg_data[f"perf-profile-level-{level}"]
            compare_config(config_resp, exp_level_data)

    print()
    if success:
        print("Everything matched! :)")
        return 0
    else:
        print("There were mismatches, please check output :(")
        return 1


if __name__ == "__main__":
    sys.exit(main())
