#!/usr/bin/python -u
import sys
from robot.libraries.BuiltIn import BuiltIn
import imp
import string
import random
import subprocess
from robot.utils import DotDict


def random_mac():
    r"""
    Return random mac address in the following format.
    Example: 00:01:6C:80:02:78
    """
    return ":".join(map(lambda x: "%02x" % x, (random.randint(0x00, 0xff)
                                               for _ in range(6))))


def random_ip():
    r"""
    Return random ip address in the following format.
    Example: 9.3.128.100
    """
    return ".".join(map(str, (random.randint(0, 255)
                              for _ in range(4))))


def get_sensor(module_name, value):
    m = imp.load_source('module.name', module_name)

    for i in m.ID_LOOKUP['SENSOR']:

        if m.ID_LOOKUP['SENSOR'][i] == value:
            return i

    return 0xFF


def get_inventory_sensor(module_name, value):
    m = imp.load_source('module.name', module_name)

    value = string.replace(value, m.INVENTORY_ROOT, '<inventory_root>')

    for i in m.ID_LOOKUP['SENSOR']:

        if m.ID_LOOKUP['SENSOR'][i] == value:
            return i

    return 0xFF


################################################################
#  This will return the URI's of the FRU type
#
#  i.e.  get_inventory_list('../data/Palmetto.py')
#
#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0/core0,
#   /org/openbmc/inventory/system/chassis/motherboard/dimm0]
################################################################
def get_inventory_list(module_name):

    inventory_list = []
    m = imp.load_source('module.name', module_name)

    for i in m.ID_LOOKUP['FRU']:
        s = m.ID_LOOKUP['FRU'][i]
        s = s.replace('<inventory_root>', m.INVENTORY_ROOT)
        inventory_list.append(s)

    return inventory_list


################################################################
#  This will return the URI's of the FRU type
#
#  i.e.  get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU')
#
#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0,
#   /org/openbmc/inventory//system/chassis/motherboard/cpu1]
################################################################
def get_inventory_fru_type_list(module_name, fru):
    inventory_list = []
    m = imp.load_source('module.name', module_name)

    for i in m.FRU_INSTANCES.keys():
        if m.FRU_INSTANCES[i]['fru_type'] == fru:
            s = i.replace('<inventory_root>', m.INVENTORY_ROOT)
            inventory_list.append(s)

    return inventory_list


################################################################
#  This will return the URI's of the FRU type that contain VPD
#
#  i.e.  get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
#
#  [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
#   /org/openbmc/inventory/system/chassis/motherboard/dimm1]
################################################################
def get_vpd_inventory_list(module_name, fru):
    inventory_list = []
    m = imp.load_source('module.name', module_name)

    for i in m.ID_LOOKUP['FRU_STR']:
        x = m.ID_LOOKUP['FRU_STR'][i]

        if m.FRU_INSTANCES[x]['fru_type'] == fru:
            s = x.replace('<inventory_root>', m.INVENTORY_ROOT)
            inventory_list.append(s)

    return inventory_list


def call_keyword(keyword):
    return BuiltIn().run_keyword(keyword)


def main():
    print get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')


if __name__ == "__main__":
    main()


def get_mtr_report(host=""):
    r"""
    Get an mtr report and return it as a dictionary of dictionaries.

    The key for the top level dictionary will be the host DNS name.  The key
    for the next level dictionary will be the field of a given row of the
    report.

    Example result:

    report:
      report[host_dummy-dnsname.com]:
        report[host_dummy-dnsname.com][row_num]:  1
        report[host_dummy-dnsname.com][host]:     host_dummy-dnsname.com
        report[host_dummy-dnsname.com][loss]:     0.0
        report[host_dummy-dnsname.com][snt]:      10
        report[host_dummy-dnsname.com][last]:     0.2
        report[host_dummy-dnsname.com][avg]:      3.5
        report[host_dummy-dnsname.com][best]:     0.2
        report[host_dummy-dnsname.com][wrst]:     32.5
        report[host_dummy-dnsname.com][stdev]:    10.2
      report[bmc-dummy-dnsname.com]:
        report[bmc-dummy-dnsname.com][row_num]:     2
        report[bmc-dummy-dnsname.com][host]:        bmc-dummy-dnsname.com
        report[bmc-dummy-dnsname.com][loss]:        0.0
        report[bmc-dummy-dnsname.com][snt]:         10
        report[bmc-dummy-dnsname.com][last]:        0.5
        report[bmc-dummy-dnsname.com][avg]:         0.5
        report[bmc-dummy-dnsname.com][best]:        0.5
        report[bmc-dummy-dnsname.com][wrst]:        0.5
        report[bmc-dummy-dnsname.com][stdev]:       0.0

    Description of arguments:
    host   The DNS name or IP address to be passed to the mtr command.
    """

    # Run the mtr command.  Exlude the header line.  Trim leading space from
    # each line.  Change all multiple spaces delims to single space delims.
    cmd_buf = "mtr --report " + host +\
        " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'"
    sub_proc = subprocess.Popen(cmd_buf, shell=True, stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
    out_buf, err_buf = sub_proc.communicate()
    shell_rc = sub_proc.returncode

    # Split the output by line.
    rows = out_buf.rstrip('\n').split("\n")

    # Initialize report dictionary.
    report = DotDict()
    for row in rows:
        # Process each row of mtr output.
        # Create a list of fields by splitting on space delimiter.
        row_list = row.split(" ")
        # Create dictionary for the row.
        row = DotDict()
        row['row_num'] = row_list[0].rstrip('.')
        row['host'] = row_list[1]
        row['loss'] = row_list[2].rstrip('%')
        row['snt'] = row_list[3]
        row['last'] = row_list[4]
        row['avg'] = row_list[5]
        row['best'] = row_list[6]
        row['wrst'] = row_list[7]
        row['stdev'] = row_list[8]
        report[row['host']] = row

    # Return the full report as dictionary of dictionaries.
    return report


def get_mtr_row(host=""):
    r"""
    Run an mtr report and get a specified row and return it as a dictionary.

    Example result:

    row:
      row[row_num]:              2
      row[host]:                 bmc-dummy-dnsname.com
      row[loss]:                 0.0
      row[snt]:                  10
      row[last]:                 0.5
      row[avg]:                  0.5
      row[best]:                 0.4
      row[wrst]:                 0.7
      row[stdev]:                0.1

    Description of arguments:
    host   The DNS name or IP address to be passed to the mtr command as
           well as the indicating which row of the report to return.
    """

    report = get_mtr_report(host)

    # The max length of host in output is 28 chars.
    row = [value for key, value in report.items() if host[0:28] in key][0]

    return row


def list_to_set(fru_list=""):
    r"""
    Pack the list into a set tuple and return.

    It may seem that this function is rather trivial. However, it simplifies
    the code and improves robot program readability and achieve the result
    required.

    Example result:

    set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
    'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])

    # Description of arguments.
    fru_list   List of FRU's elements.
    """
    return set(fru_list)


def min_list_value(value_list):
    r"""
    Returns the element from the list with minimum value.
    """
    return min(value_list)
