#!/usr/bin/env python

r"""
This module provides many valuable bmc ssh functions such as
bmc_execute_command.
"""

import sys
try:
    import exceptions
except ImportError:
    import builtins as exception
import re
import gen_print as gp
import gen_valid as gv
import gen_robot_ssh as grs
from robot.libraries.BuiltIn import BuiltIn


def bmc_execute_command(cmd_buf,
                        print_out=0,
                        print_err=0,
                        ignore_err=0,
                        fork=0,
                        quiet=None,
                        test_mode=None,
                        time_out=None):
    r"""
    Run the given command in an BMC SSH session and return the stdout, stderr
    and the return code.

    This function will obtain the global values for OPENBMC_HOST,
    OPENBMC_USERNAME, etc.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    time_out                        The amount of time to allow for the
                                    execution of cmd_buf.  A value of None
                                    means that there is no limit to how long
                                    the command may take.
    """

    # Get global BMC variable values.
    openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}", default="")
    openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}",
                                                    default="")
    openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}",
                                                    default="")

    if not gv.valid_value(openbmc_host):
        return "", "", 1
    if not gv.valid_value(openbmc_username):
        return "", "", 1
    if not gv.valid_value(openbmc_password):
        return "", "", 1

    open_connection_args = {'host': openbmc_host, 'alias': 'bmc_connection',
                            'timeout': '25.0', 'prompt': '# '}
    login_args = {'username': openbmc_username, 'password': openbmc_password}

    return grs.execute_ssh_command(cmd_buf, open_connection_args, login_args,
                                   print_out, print_err, ignore_err, fork,
                                   quiet, test_mode, time_out)


def os_execute_command(cmd_buf,
                       print_out=0,
                       print_err=0,
                       ignore_err=0,
                       fork=0,
                       quiet=None,
                       test_mode=None,
                       time_out=None):
    r"""
    Run the given command in an OS SSH session and return the stdout, stderr
    and the return code.

    This function will obtain the global values for OS_HOST, OS_USERNAME, etc.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    time_out                        The amount of time to allow for the
                                    execution of cmd_buf.  A value of None
                                    means that there is no limit to how long
                                    the command may take.
    """

    # Get global OS variable values.
    os_host = BuiltIn().get_variable_value("${OS_HOST}", default="")
    os_username = BuiltIn().get_variable_value("${OS_USERNAME}",
                                               default="")
    os_password = BuiltIn().get_variable_value("${OS_PASSWORD}",
                                               default="")

    if not gv.valid_value(os_host):
        return "", "", 1
    if not gv.valid_value(os_username):
        return "", "", 1
    if not gv.valid_value(os_password):
        return "", "", 1

    open_connection_args = {'host': os_host, 'alias': 'os_connection'}
    login_args = {'username': os_username, 'password': os_password}

    return grs.execute_ssh_command(cmd_buf, open_connection_args, login_args,
                                   print_out, print_err, ignore_err, fork,
                                   quiet, test_mode, time_out)


def xcat_execute_command(cmd_buf,
                         print_out=0,
                         print_err=0,
                         ignore_err=0,
                         fork=0,
                         quiet=None,
                         test_mode=None):
    r"""
    Run the given command in an XCAT SSH session and return the stdout, stderr
    and the return code.

    This function will obtain the global values for XCAT_HOST, XCAT_USERNAME,
    etc.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    """

    # Get global XCAT variable values.
    xcat_host = BuiltIn().get_variable_value("${XCAT_HOST}", default="")
    xcat_username = BuiltIn().get_variable_value("${XCAT_USERNAME}",
                                                 default="")
    xcat_password = BuiltIn().get_variable_value("${XCAT_PASSWORD}",
                                                 default="")
    xcat_port = BuiltIn().get_variable_value("${XCAT_PORT}",
                                             default="22")

    if not gv.valid_value(xcat_host):
        return "", "", 1
    if not gv.valid_value(xcat_username):
        return "", "", 1
    if not gv.valid_value(xcat_password):
        return "", "", 1
    if not gv.valid_value(xcat_port):
        return "", "", 1

    open_connection_args = {'host': xcat_host, 'alias': 'xcat_connection',
                            'port': xcat_port}
    login_args = {'username': xcat_username, 'password': xcat_password}

    return grs.execute_ssh_command(cmd_buf, open_connection_args, login_args,
                                   print_out, print_err, ignore_err, fork,
                                   quiet, test_mode)


def device_write(cmd_buf,
                 print_out=0,
                 quiet=None,
                 test_mode=None):
    r"""
    Write the given command in a device SSH session and return the stdout,
    stderr and the return code.

    This function is useful for writing to a switch.

    This function will obtain the global values for DEVICE_HOST,
    DEVICE_USERNAME, etc.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    """

    # Get global DEVICE variable values.
    device_host = BuiltIn().get_variable_value("${DEVICE_HOST}", default="")
    device_username = BuiltIn().get_variable_value("${DEVICE_USERNAME}",
                                                   default="")
    device_password = BuiltIn().get_variable_value("${DEVICE_PASSWORD}",
                                                   default="")
    device_port = BuiltIn().get_variable_value("${DEVICE_PORT}",
                                               default="22")

    if not gv.valid_value(device_host):
        return "", "", 1
    if not gv.valid_value(device_username):
        return "", "", 1
    if not gv.valid_value(device_password):
        return "", "", 1
    if not gv.valid_value(device_port):
        return "", "", 1

    open_connection_args = {'host': device_host, 'alias': 'device_connection',
                            'port': device_port}
    login_args = {'username': device_username, 'password': device_password}

    return grs.execute_ssh_command(cmd_buf, open_connection_args, login_args,
                                   print_out, print_err=0, ignore_err=1,
                                   fork=0, quiet=quiet, test_mode=test_mode)
