#!/usr/bin/env python3

"""Tool to visualize PLDM PDR's"""

import argparse
import json
import hashlib
import sys
from datetime import datetime
import paramiko
from graphviz import Digraph
from tabulate import tabulate
import os
import shlex
import shutil
import subprocess


class Process:
    """ Interface definition for interacting with a process created by an
        Executor."""

    def __init__(self, stdout, stderr):
        """ Construct a Process object.  Process object clients can read the
            process stdout and stderr with os.read(), and can wait for the
            process to exit.

            Parameters:
                stdout: os.read()able stream representing stdout
                stderr: os.read()able stream representing stderr
        """

        self.stdout = stdout
        self.stderr = stderr

    def wait(self):
        """ Wait for the process to finish, and return its exit status."""

        raise NotImplementedError


class Executor:
    """ Interface definition for interacting with executors.  An executor is an
        object that can run a program."""

    def exec_command(self, cmd):
        raise NotImplementedError

    def close(self):
        pass


class ParamikoProcess(Process):
    """ Concrete implementation of the Process interface that adapts Paramiko
        interfaces to the Process interface requirements."""

    def __init__(self, stdout, stderr):
        super(ParamikoProcess, self).__init__(stdout, stderr)

    def wait(self):
        return self.stderr.channel.recv_exit_status()


class ParamikoExecutor(Executor):
    """ Concrete implementation of the Executor interface that uses
        Paramiko to connect to a remote BMC to run the program."""

    def __init__(self, hostname, uname, passwd, port, **kw):
        """ This function is responsible for connecting to the BMC via
            ssh and returning an executor object.

            Parameters:
                hostname: hostname/IP address of BMC
                uname: ssh username of BMC
                passwd: ssh password of BMC
                port: ssh port of BMC
        """

        super(ParamikoExecutor, self).__init__()
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(
            hostname, username=uname, password=passwd, port=port, **kw)

    def exec_command(self, cmd):
        _, stdout, stderr = self.client.exec_command(cmd)
        return ParamikoProcess(stdout, stderr)

    def close(self):
        self.client.close()


class SubprocessProcess(Process):
    def __init__(self, popen):
        self.popen = popen
        super(SubprocessProcess, self).__init__(popen.stdout, popen.stderr)

    def wait(self):
        self.popen.wait()
        return self.popen.returncode


class SubprocessExecutor(Executor):
    def __init__(self):
        super(SubprocessExecutor, self).__init__()

    def exec_command(self, cmd):
        args = shlex.split(cmd)
        args[0] = shutil.which(args[0])
        p = subprocess.Popen(
            args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return SubprocessProcess(p)


def prepare_summary_report(state_sensor_pdr, state_effecter_pdr):

    """ This function is responsible to parse the state sensor pdr
        and the state effecter pdr dictionaries and creating the
        summary table.

        Parameters:
            state_sensor_pdr: list of state sensor pdrs
            state_effecter_pdr: list of state effecter pdrs

    """

    summary_table = []
    headers = ["sensor_id", "entity_type", "state_set", "states"]
    summary_table.append(headers)
    for value in state_sensor_pdr.values():
        summary_record = []
        sensor_possible_states = ''
        for sensor_state in value["possibleStates[0]"]:
            sensor_possible_states += sensor_state+"\n"
        summary_record.extend([value["sensorID"], value["entityType"],
                               value["stateSetID[0]"],
                               sensor_possible_states])
        summary_table.append(summary_record)
    print("Created at : ", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    print(tabulate(summary_table, tablefmt="fancy_grid", headers="firstrow"))

    summary_table = []
    headers = ["effecter_id", "entity_type", "state_set", "states"]
    summary_table.append(headers)
    for value in state_effecter_pdr.values():
        summary_record = []
        effecter_possible_states = ''
        for state in value["possibleStates[0]"]:
            effecter_possible_states += state+"\n"
        summary_record.extend([value["effecterID"], value["entityType"],
                               value["stateSetID[0]"],
                               effecter_possible_states])
        summary_table.append(summary_record)
    print(tabulate(summary_table, tablefmt="fancy_grid", headers="firstrow"))


def draw_entity_associations(pdr, counter):

    """ This function is responsible to create a picture that captures
        the entity association hierarchy based on the entity association
        PDR's received from the BMC.

        Parameters:
            pdr: list of entity association PDR's
            counter: variable to capture the count of PDR's to unflatten
                     the tree

    """

    dot = Digraph('entity_hierarchy', node_attr={'color': 'lightblue1',
                                                 'style': 'filled'})
    dot.attr(label=r'\n\nEntity Relation Diagram < ' +
             str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))+'>\n')
    dot.attr(fontsize='20')
    edge_list = []
    for value in pdr.values():
        parentnode = str(value["containerEntityType"]) + \
                     str(value["containerEntityInstanceNumber"])
        dot.node(hashlib.md5((parentnode +
                              str(value["containerEntityContainerID"]))
                             .encode()).hexdigest(), parentnode)

        for i in range(1, value["containedEntityCount"]+1):
            childnode = str(value[f"containedEntityType[{i}]"]) + \
                        str(value[f"containedEntityInstanceNumber[{i}]"])
            cid = str(value[f"containedEntityContainerID[{i}]"])
            dot.node(hashlib.md5((childnode + cid)
                                 .encode()).hexdigest(), childnode)

            if[hashlib.md5((parentnode +
                            str(value["containerEntityContainerID"]))
                           .encode()).hexdigest(),
               hashlib.md5((childnode + cid)
                           .encode()).hexdigest()] not in edge_list:
                edge_list.append([hashlib.md5((parentnode +
                                  str(value["containerEntityContainerID"]))
                                              .encode()).hexdigest(),
                                  hashlib.md5((childnode + cid)
                                              .encode()).hexdigest()])
                dot.edge(hashlib.md5((parentnode +
                                      str(value["containerEntityContainerID"]))
                                     .encode()).hexdigest(),
                         hashlib.md5((childnode + cid).encode()).hexdigest())
    unflattentree = dot.unflatten(stagger=(round(counter/3)))
    unflattentree.render(filename='entity_association_' +
                         str(datetime.now().strftime("%Y-%m-%d_%H-%M-%S")),
                         view=False, cleanup=True, format='pdf')


class PLDMToolError(Exception):
    """ Exception class intended to be used to hold pldmtool invocation failure
        information such as exit status and stderr.

    """

    def __init__(self, status, stderr):
        msg = "pldmtool failed with exit status {}.\n".format(status)
        msg += "stderr: \n\n{}".format(stderr)
        super(PLDMToolError, self).__init__(msg)
        self.status = status

    def get_status(self):
        return self.status


def process_pldmtool_output(process):
    """ Ensure pldmtool runs without error and if it does fail, detect that and
        show the pldmtool exit status and it's stderr.

        A simpler implementation would just wait for the pldmtool exit status
        prior to attempting to decode it's stdout.  Instead, optimize for the
        no error case and allow the json decoder to consume pldmtool stdout as
        soon as it is available (in parallel).  This results in the following
        error scenarios:
            - pldmtool fails and the decoder fails
              Ignore the decoder fail and throw PLDMToolError.
            - pldmtool fails and the decoder doesn't fail
              Throw PLDMToolError.
            - pldmtool doesn't fail and the decoder does fail
              This is a pldmtool bug - re-throw the decoder error.

        Parameters:
            process: A Process object providing process control functions like
                     wait, and access functions such as reading stdout and
                     stderr.

    """

    status = 0
    try:
        data = json.load(process.stdout)
        # it's unlikely, but possible, that pldmtool failed but still wrote a
        # valid json document - so check for that.
        status = process.wait()
        if status == 0:
            return data
    except json.decoder.JSONDecodeError:
        # pldmtool wrote an invalid json document.  Check to see if it had
        # non-zero exit status.
        status = process.wait()
        if status == 0:
            # pldmtool didn't have non zero exit status, so it wrote an invalid
            # json document and the JSONDecodeError is the correct error.
            raise

    # pldmtool had a non-zero exit status, so throw an error for that, possibly
    # discarding a spurious JSONDecodeError exception.
    raise PLDMToolError(status, "".join(process.stderr))


def get_pdrs_one_at_a_time(executor):
    """ Using pldmtool, generate (record handle, PDR) tuples for each record in
        the PDR repository.

        Parameters:
            executor: executor object for running pldmtool

    """

    command_fmt = 'pldmtool platform getpdr -d {}'
    record_handle = 0
    while True:
        process = executor.exec_command(command_fmt.format(str(record_handle)))
        pdr = process_pldmtool_output(process)
        yield record_handle, pdr
        record_handle = pdr["nextRecordHandle"]
        if record_handle == 0:
            break


def get_all_pdrs_at_once(executor):
    """ Using pldmtool, generate (record handle, PDR) tuples for each record in
        the PDR repository.  Use pldmtool platform getpdr --all.

        Parameters:
            executor: executor object for running pldmtool

    """

    process = executor.exec_command('pldmtool platform getpdr -a')
    all_pdrs = process_pldmtool_output(process)

    # Explicitly request record 0 to find out what the real first record is.
    process = executor.exec_command('pldmtool platform getpdr -d 0')
    pdr_0 = process_pldmtool_output(process)
    record_handle = pdr_0["recordHandle"]

    while True:
        for pdr in all_pdrs:
            if pdr["recordHandle"] == record_handle:
                yield record_handle, pdr
                record_handle = pdr["nextRecordHandle"]
                if record_handle == 0:
                    return
        raise RuntimeError(
            "Dangling reference to record {}".format(record_handle))


def get_pdrs(executor):
    """ Using pldmtool, generate (record handle, PDR) tuples for each record in
        the PDR repository.  Use pldmtool platform getpdr --all or fallback on
        getting them one at a time if pldmtool doesn't support the --all
        option.

        Parameters:
            executor: executor object for running pldmtool

    """
    try:
        for record_handle, pdr in get_all_pdrs_at_once(executor):
            yield record_handle, pdr
        return
    except PLDMToolError as e:
        # No support for the -a option
        if e.get_status() != 106:
            raise
    except json.decoder.JSONDecodeError as e:
        # Some versions of pldmtool don't print valid json documents with -a
        if e.msg != "Extra data":
            raise

    for record_handle, pdr in get_pdrs_one_at_a_time(executor):
        yield record_handle, pdr


def fetch_pdrs_from_bmc(executor):

    """ This is the core function that would fire the getPDR pldmtool command
        and it then agreegates the data received from all the calls into the
        respective dictionaries based on the PDR Type.

        Parameters:
            executor: executor object for running pldmtool

    """

    entity_association_pdr = {}
    state_sensor_pdr = {}
    state_effecter_pdr = {}
    state_effecter_pdr = {}
    numeric_pdr = {}
    fru_record_set_pdr = {}
    tl_pdr = {}
    for handle_number, my_dic in get_pdrs(executor):
        sys.stdout.write("Fetching PDR's from BMC : %8d\r" % (handle_number))
        sys.stdout.flush()
        if my_dic["PDRType"] == "Entity Association PDR":
            entity_association_pdr[handle_number] = my_dic
        if my_dic["PDRType"] == "State Sensor PDR":
            state_sensor_pdr[handle_number] = my_dic
        if my_dic["PDRType"] == "State Effecter PDR":
            state_effecter_pdr[handle_number] = my_dic
        if my_dic["PDRType"] == "FRU Record Set PDR":
            fru_record_set_pdr[handle_number] = my_dic
        if my_dic["PDRType"] == "Terminus Locator PDR":
            tl_pdr[handle_number] = my_dic
        if my_dic["PDRType"] == "Numeric Effecter PDR":
            numeric_pdr[handle_number] = my_dic
    executor.close()

    total_pdrs = len(entity_association_pdr.keys()) + len(tl_pdr.keys()) + \
        len(state_effecter_pdr.keys()) + len(numeric_pdr.keys()) + \
        len(state_sensor_pdr.keys()) + len(fru_record_set_pdr.keys())
    print("\nSuccessfully fetched " + str(total_pdrs) + " PDR\'s")
    print("Number of FRU Record PDR's : ", len(fru_record_set_pdr.keys()))
    print("Number of TerminusLocator PDR's : ", len(tl_pdr.keys()))
    print("Number of State Sensor PDR's : ", len(state_sensor_pdr.keys()))
    print("Number of State Effecter PDR's : ", len(state_effecter_pdr.keys()))
    print("Number of Numeric Effecter PDR's : ", len(numeric_pdr.keys()))
    print("Number of Entity Association PDR's : ",
          len(entity_association_pdr.keys()))
    return (entity_association_pdr, state_sensor_pdr,
            state_effecter_pdr, len(fru_record_set_pdr.keys()))


def main():

    """ Create a summary table capturing the information of all the PDR's
        from the BMC & also create a diagram that captures the entity
        association hierarchy."""

    parser = argparse.ArgumentParser(prog='pldm_visualise_pdrs.py')
    parser.add_argument('--bmc', type=str, help="BMC IPAddress/BMC Hostname")
    parser.add_argument('--user', type=str, help="BMC username")
    parser.add_argument('--password', type=str, help="BMC Password")
    parser.add_argument('--port', type=int, help="BMC SSH port",
                        default=22)
    args = parser.parse_args()

    extra_cfg = {}
    if args.bmc:
        try:
            with open(os.path.expanduser("~/.ssh/config")) as f:
                ssh_config = paramiko.SSHConfig()
                ssh_config.parse(f)
                host_config = ssh_config.lookup(args.bmc)
                if host_config:
                    if 'hostname' in host_config:
                        args.bmc = host_config['hostname']
                    if 'user' in host_config and args.user is None:
                        args.user = host_config['user']
                    if 'proxycommand' in host_config:
                        extra_cfg['sock'] = paramiko.ProxyCommand(
                            host_config['proxycommand'])
        except FileNotFoundError:
            pass

        executor = ParamikoExecutor(
            args.bmc, args.user, args.password, args.port, **extra_cfg)
    elif shutil.which('pldmtool'):
        executor = SubprocessExecutor()
    else:
        sys.exit("Can't find any PDRs: specify remote BMC with --bmc or "
                 "install pldmtool.")

    association_pdr, state_sensor_pdr, state_effecter_pdr, counter = \
        fetch_pdrs_from_bmc(executor)
    draw_entity_associations(association_pdr, counter)
    prepare_summary_report(state_sensor_pdr, state_effecter_pdr)


if __name__ == "__main__":
    main()
