#!/usr/bin/env python

r"""
This file contains functions which are useful for processing BMC dumps.
"""

import gen_print as gp
import gen_misc as gm
import gen_robot_keyword as grk
import bmc_ssh_utils as bsu
import var_funcs as vf
import os
from robot.libraries.BuiltIn import BuiltIn
import sys
import os
import imp
base_path = os.path.dirname(os.path.dirname(
                            imp.find_module("gen_robot_print")[1])) + os.sep
sys.path.append(base_path + "data/")
import variables as var


def get_dump_dict(quiet=None):
    r"""
    Get dump information and return as an ordered dictionary where the keys
    are the dump IDs and the values are the full path names of the dumps.

    Example robot program call:

    ${dump_dict}=  Get Dump Dict
    Rpvars                          1  dump_dict

    Example output:

    dump_dict:
      [1]:
      /var/lib/phosphor-debug-collector/dumps/1/obmcdump_1_1508255216.tar.xz
      [2]:
      /var/lib/phosphor-debug-collector/dumps/2/obmcdump_2_1508255245.tar.xz
      [3]:
      /var/lib/phosphor-debug-collector/dumps/3/obmcdump_3_1508255267.tar.xz
      [4]:
      /var/lib/phosphor-debug-collector/dumps/4/obmcdump_4_1508255283.tar.xz

    Description of argument(s):
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    quiet = int(gp.get_var_value(quiet, 1))
    cmd_buf = "dump_dir_path=" + var.DUMP_DIR_PATH + " ; " \
              + "for dump_id in $(ls ${dump_dir_path} | sort -n) ; " \
              + "do echo -n $dump_id: ; ls ${dump_dir_path}${dump_id}/* ; done"
    output, stderr, rc = bsu.bmc_execute_command(cmd_buf, quiet=quiet)

    return vf.key_value_outbuf_to_dict(output)


def valid_dump(dump_id,
               dump_dict=None,
               quiet=None):
    r"""
    Verify that dump_id is a valid.  If it is not valid, issue robot failure
    message.

    A dump is valid if the indicated dump_id refers to an existing dump with a
    valid associated dump file.

    Description of argument(s):
    dump_id                         A dump ID (e.g. "1", "2", etc.)
    dump_dict                       A dump dictionary such as the one returned
                                    by get_dump_dict.  If this value is None,
                                    this function will call get_dump_dict on
                                    the caller's behalf.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    if dump_dict is None:
        dump_dict = get_dump_dict(quiet=quiet)

    if dump_id not in dump_dict:
        message = "The specified dump ID was not found among the existing" \
            + " dumps:\n"
        message += gp.sprint_var(dump_id)
        message += gp.sprint_var(dump_dict)
        BuiltIn().fail(gp.sprint_error(message))

    if not dump_dict[dump_id].endswith("tar.xz"):
        message = "There is no \"tar.xz\" file associated with the given" \
            + " dump_id:\n"
        message += gp.sprint_var(dump_id)
        dump_file_path = dump_dict[dump_id]
        message += gp.sprint_var(dump_file_path)
        BuiltIn().fail(gp.sprint_error(message))


def scp_dumps(targ_dir_path,
              targ_file_prefix="",
              dump_dict=None,
              quiet=None):
    r"""
    SCP all dumps from the BMC to the indicated directory on the local system
    and return a list of the new files.

    Description of argument(s):
    targ_dir_path                   The path of the directory to receive the
                                    dump files.
    targ_file_prefix                Prefix which will be pre-pended to each
                                    target file's name.
    dump_dict                       A dump dictionary such as the one returned
                                    by get_dump_dict.  If this value is None,
                                    this function will call get_dump_dict on
                                    the caller's behalf.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    targ_dir_path = gm.add_trailing_slash(targ_dir_path)

    if dump_dict is None:
        dump_dict = get_dump_dict(quiet=quiet)

    status, ret_values = grk.run_key("Open Connection for SCP", quiet=quiet)

    dump_file_list = []
    for dump_id, source_file_path in dump_dict.iteritems():
        targ_file_path = targ_dir_path + targ_file_prefix \
            + os.path.basename(source_file_path)
        status, ret_values = grk.run_key("scp.Get File  " + source_file_path
                                         + "  " + targ_file_path, quiet=quiet)
        dump_file_list.append(targ_file_path)

    return dump_file_list
