#!/usr/bin/env python3

r"""
PEL functions.
"""

import func_args as fa
import bmc_ssh_utils as bsu
import json
import os
import sys
from robot.libraries.BuiltIn import BuiltIn

base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_path + "/data/")

import pel_variables


class peltool_exception(Exception):
    r"""
    Base class for peltool related exceptions.
    """

    def __init__(self, message):
        self.message = message
        super().__init__(self.message)


def peltool(option_string, parse_json=True, **bsu_options):
    r"""
    Run peltool on the BMC with the caller's option string and return the result.

    Example:

    ${pel_results}=  Peltool  -l
    Rprint Vars  pel_results

    pel_results:
      [0x50000031]:
        [CompID]:                       0x1000
        [PLID]:                         0x50000031
        [Subsystem]:                    BMC Firmware
        [Message]:                      An application had an internal failure
        [SRC]:                          BD8D1002
        [Commit Time]:                  02/25/2020  04:51:31
        [Sev]:                          Unrecoverable Error
        [CreatorID]:                    BMC

    Description of argument(s):
    option_string                   A string of options which are to be processed by the peltool command.
    parse_json                      Indicates that the raw JSON data should parsed into a list of
                                    dictionaries.
    bsu_options                     Options to be passed directly to bmc_execute_command. See its prolog for
                                    details.
    """

    bsu_options = fa.args_to_objects(bsu_options)
    out_buf, stderr, rc = bsu.bmc_execute_command('peltool ' + option_string, **bsu_options)
    if parse_json:
        try:
            return json.loads(out_buf)
        except ValueError:
            return {}
    return out_buf


def get_pel_data_from_bmc():
    r"""
    Returns PEL data from BMC else throws exception.
    """
    try:
        pel_data = peltool(" -l")
        if not pel_data:
            print("No PEL data present in BMC ...")
    except Exception as e:
        raise peltool_exception("Failed to get PEL data from BMC : " + str(e))
    return pel_data


def fetch_all_pel_ids_for_src(src_id, severity):
    r"""
    Fetch all PEL IDs for the input SRC ID based on the severity type
    in the list format.

    Description of arguments:
    src_id      SRC ID (e.g. BC20E504).
    severity    PEL severity (e.g. "Predictive Error"
                                   "Recovered Error").
    """

    try:
        src_pel_ids = []
        pel_data = get_pel_data_from_bmc()
        pel_id_list = pel_data.keys()
        for pel_id in pel_id_list:
            # Check if required SRC ID with severity is present
            if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)):
                src_pel_ids.append(pel_id)

        if not src_pel_ids:
            raise peltool_exception(src_id + " with severity " + severity + " not present")
    except Exception as e:
        raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e))
    return src_pel_ids


def verify_src_signature_and_threshold(pel_id, attn_type, signature_desc, th_limit):
    r"""
    Verifies SRC details for the given PEL ID based on the required
    attention type, signature description, threshold limits.

    Description of arguments:
    pel_id          PEL ID for the required SRC details to verify.
    attn_type       Attention type (e.g. RE, CS, UNIT_CS).
    signature_desc  Signature description of the error inject.
    th_limit        Threshold limit (e.g. 1, 5, 32).
    """

    try:
        pel_cmd = " -i " + pel_id
        src_data = peltool(pel_cmd)
        src_dict = src_data["Primary SRC"]["SRC Details"]
        usr_data = src_data["User Data 1"]

        # Example for signature in recoverable error
        #
        # "SRC Details": {
        # "Attention Type": "RECOVERABLE",
        # "Node": 0,
        # "Target Type": "TYPE_OMIC",
        # "Target Instance": 0,
        # "Signature": "MC_OMI_DL_FIR[1]: OMI-DL0 UE on data flit"
        # }
        if (attn_type == "RE"):
            if (src_dict["Attention Type"] != "RECOVERABLE"):
                raise peltool_exception("Required Attention type " + attn_type + " not found")

        # Example for signature in system checkstop error
        #
        # "SRC Details": {
        # "Primary Attention": "system checkstop",
        # "Signature Description": {
        #    "Chip Desc": "node 0 proc 0 (P10 2.0)",
        #    "Signature": "EQ_L2_FIR(0)[7] L2 directory read UE",
        #    "Attn Type": "checkstop"
        # }

        elif (attn_type == "CS"):
            if (src_dict["Primary Attention"] != "system checkstop"):
                raise peltool_exception("Required Attention type " + attn_type + " not found")

        elif (attn_type == "UNIT_CS"):
            if (src_dict["Attention Type"] != "UNIT_CS"):
                raise peltool_exception("Required Attention type " + attn_type + " not found")
        else:
            raise peltool_exception("Required Attention type " + attn_type + " not found")

        if signature_desc not in src_dict["Signature"]:
            raise peltool_exception("Required Signature " + signature_desc + " not found")

        if (int(th_limit) != usr_data["Error Count"]):
            raise peltool_exception("Required Threshold limit " + th_limit + " not found")

    except Exception as e:
        raise peltool_exception("Failed to verify SRC details : " + str(e))
    return True


def fetch_all_src():
    r"""
    Fetch all SRC IDs from peltool in the list format.
    """
    try:
        src_id = []
        pel_data = get_pel_data_from_bmc()
        if pel_data:
            pel_id_list = pel_data.keys()
            for pel_id in pel_id_list:
                src_id.append(pel_data[pel_id]["SRC"])
        else:
            raise peltool_exception("No PEL entry found ..")
    except Exception as e:
        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
    return src_id
