#!/usr/bin/env python3

r"""
See class prolog below for details.
"""

import importlib
import json
import logging
import os
import platform
import re
import subprocess
import sys
import time
from errno import EACCES, EPERM
from typing import Any

import yaml

sys.dont_write_bytecode = True


script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(script_dir)
# Walk path and append to sys.path
for root, dirs, files in os.walk(script_dir):
    for dir in dirs:
        sys.path.append(os.path.join(root, dir))

from ssh_utility import SSHRemoteclient  # NOQA
from telnet_utility import TelnetRemoteclient  # NOQA

r"""
This is for plugin functions returning data or responses to the caller
in YAML plugin setup.

Example:

    - plugin:
      - plugin_name: plugin.ssh_execution
      - plugin_function: version = ssh_execute_cmd
      - plugin_args:
        - ${hostname}
        - ${username}
        - ${password}
        - "cat /etc/os-release | grep VERSION_ID | awk -F'=' '{print $2}'"
     - plugin:
        - plugin_name: plugin.print_vars
        - plugin_function: print_vars
        - plugin_args:
          - version

where first plugin "version" var is used by another plugin in the YAML
block or plugin

"""
# Global variables for storing plugin return values, plugin return variables,
# and log storage path.
global global_log_store_path
global global_plugin_dict
global global_plugin_list
global global_plugin_type_list
global global_plugin_error_dict

# Hold the plugin return values in a dictionary and plugin return variables in
# a list. The dictionary is used for referencing and updating variables during
# parsing in the parser, while the list is used for storing current variables
# from the plugin block that need processing.
global_plugin_dict = {}
global_plugin_list = []

# Hold the plugin return named variables if the function returned values are
# lists or dictionaries. This list is used to reference the plugin dictionary
# for python function execute arguments.
# Example: ['version']
global_plugin_type_list = []

# Path where logs are to be stored or written.
global_log_store_path = ""

# Plugin error state defaults.
global_plugin_error_dict = {
    "exit_on_error": False,
    "continue_on_error": False,
}


def execute_python_function(module_name, function_name, *args, **kwargs):
    r"""
    Execute a Python function from a module dynamically.

    This function dynamically imports a module and executes a specified
    function from that module with the provided arguments. The function takes
    the module name, function name, and arguments as input. The function
    returns the result of the executed function.

    If an ImportError or AttributeError occurs, the function prints an error
    message and returns None.

    Parameters:
        module_name (str):   The name of the module containing the function.
        function_name (str): The name of the function to execute.
        *args:               Positional arguments to pass to the function.
        **kwargs:            Keyword arguments to pass to the function.

    Returns:
        Any: The result of the executed function or None if an error occurs.
    """
    try:
        # Dynamically import the module.
        module = importlib.import_module(module_name)

        # Get the function from the module.
        func = getattr(module, function_name)

        # Call the function with the provided arguments.
        result = func(*args, **kwargs)

    except (ImportError, AttributeError) as e:
        print(f"\tERROR: execute_python_function: {e}")
        # Set the plugin error state.
        global_plugin_error_dict["exit_on_error"] = True
        print("\treturn: PLUGIN_EXEC_ERROR")
        return "PLUGIN_EXEC_ERROR"

    return result


class ffdc_collector:
    r"""
    Execute commands from a configuration file to collect log files and store
    the generated files at the specified location.

    This class is designed to execute commands specified in a configuration
    YAML file to collect log files from a remote host.

    The class establishes connections using SSH, Telnet, or other protocols
    based on the configuration. It fetches and stores the generated files at
    the specified location. The class provides methods for initializing the
    collector, executing commands, and handling errors.
    """

    def __init__(
        self,
        hostname,
        username,
        password,
        port_ssh,
        port_https,
        port_ipmi,
        ffdc_config,
        location,
        remote_type,
        remote_protocol,
        env_vars,
        econfig,
        log_level,
    ):
        r"""
        Initialize the FFDCCollector object with the provided parameters.

        This method initializes an FFDCCollector object with the given
        attributes. The attributes represent the configuration for connecting
        to a remote system, collecting log data, and storing the collected
        data.

        Parameters:
            hostname (str):             Name or IP address of the targeted
                                        (remote) system.
            username (str):             User on the targeted system with access
                                        to log files.
            password (str):             Password for the user on the targeted
                                        system.
            port_ssh (int, optional):   SSH port value. Defaults to 22.
            port_https (int, optional): HTTPS port value. Defaults to 443.
            port_ipmi (int, optional):  IPMI port value. Defaults to 623.
            ffdc_config (str):          Configuration file listing commands
                                        and files for FFDC.
            location (str):             Where to store collected log data.
            remote_type (str):          Block YAML type name of the remote
                                        host.
            remote_protocol (str):      Protocol to use to collect data.
            env_vars (dict, optional):  User-defined CLI environment variables.
                                        Defaults to None.
            econfig (str, optional):    User-defined environment variables
                                        YAML file. Defaults to None.
            log_level (str, optional):  Log level for the collector.
                                        Defaults to "INFO".
        """

        self.hostname = hostname
        self.username = username
        self.password = password
        self.port_ssh = str(port_ssh)
        self.port_https = str(port_https)
        self.port_ipmi = str(port_ipmi)
        self.ffdc_config = ffdc_config
        self.location = location + "/" + remote_type.upper()
        self.ssh_remoteclient = None
        self.telnet_remoteclient = None
        self.ffdc_dir_path = ""
        self.ffdc_prefix = ""
        self.target_type = remote_type.upper()
        self.remote_protocol = remote_protocol.upper()
        self.env_vars = env_vars if env_vars else {}
        self.econfig = econfig if econfig else {}
        self.start_time = 0
        self.elapsed_time = ""
        self.env_dict = {}
        self.logger = None

        """
        Set prefix values for SCP files and directories.
        Since the time stamp is at second granularity, these values are set
        here to be sure that all files for this run will have the same
        timestamps and be saved in the same directory.
        self.location == local system for now
        """
        self.set_ffdc_default_store_path()

        # Logger for this run.  Need to be after set_ffdc_default_store_path()
        self.script_logging(getattr(logging, log_level.upper()))

        # Verify top level directory exists for storage
        self.validate_local_store(self.location)

        if self.verify_script_env():
            try:
                with open(self.ffdc_config, "r") as file:
                    self.ffdc_actions = yaml.safe_load(file)
            except yaml.YAMLError as e:
                self.logger.error(e)
                sys.exit(-1)

            if self.target_type not in self.ffdc_actions:
                self.logger.error(
                    "\n\tERROR: %s is not listed in %s.\n\n"
                    % (self.target_type, self.ffdc_config)
                )
                sys.exit(-1)

            self.logger.info("\n\tENV: User define input YAML variables")
            self.load_env()
        else:
            sys.exit(-1)

    def verify_script_env(self):
        r"""
        Verify that all required environment variables are set.

        This method checks if all required environment variables are set.
        If any required variable is missing, the method returns False.
        Otherwise, it returns True.

        Returns:
            bool: True if all required environment variables are set,
            False otherwise.
        """
        # Import to log version
        import click
        import paramiko

        run_env_ok = True

        try:
            redfishtool_version = (
                self.run_tool_cmd("redfishtool -V").split(" ")[2].strip("\n")
            )
        except Exception as e:
            self.logger.error("\tEXCEPTION redfishtool: %s", e)
            redfishtool_version = "Not Installed (optional)"

        try:
            ipmitool_version = self.run_tool_cmd("ipmitool -V").split(" ")[2]
        except Exception as e:
            self.logger.error("\tEXCEPTION ipmitool: %s", e)
            ipmitool_version = "Not Installed (optional)"

        self.logger.info("\n\t---- Script host environment ----")
        self.logger.info(
            "\t{:<10}  {:<10}".format("Script hostname", os.uname()[1])
        )
        self.logger.info(
            "\t{:<10}  {:<10}".format("Script host os", platform.platform())
        )
        self.logger.info(
            "\t{:<10}  {:>10}".format("Python", platform.python_version())
        )
        self.logger.info("\t{:<10}  {:>10}".format("PyYAML", yaml.__version__))
        self.logger.info("\t{:<10}  {:>10}".format("click", click.__version__))
        self.logger.info(
            "\t{:<10}  {:>10}".format("paramiko", paramiko.__version__)
        )
        self.logger.info(
            "\t{:<10}  {:>9}".format("redfishtool", redfishtool_version)
        )
        self.logger.info(
            "\t{:<10}  {:>12}".format("ipmitool", ipmitool_version)
        )

        if eval(yaml.__version__.replace(".", ",")) < (5, 3, 0):
            self.logger.error(
                "\n\tERROR: Python or python packages do not meet minimum"
                " version requirement."
            )
            self.logger.error(
                "\tERROR: PyYAML version 5.3.0 or higher is needed.\n"
            )
            run_env_ok = False

        self.logger.info("\t---- End script host environment ----")
        return run_env_ok

    def script_logging(self, log_level_attr):
        """
        Create a logger for the script with the specified log level.

        This method creates a logger for the script with the specified
        log level. The logger is configured to write log messages to a file
        and the console.

        self.logger = logging.getLogger(__name__)

        Setting logger with __name__ will add the trace
        Example:

            INFO:ffdc_collector:    System Type: BMC

        Currently, set to empty purposely to log as
            System Type: BMC

        Parameters:
            log_level_attr (str):   The log level for the logger
                                    (e.g., "DEBUG", "INFO", "WARNING",
                                    "ERROR", "CRITICAL").

        Returns:
            None
        """
        self.logger = logging.getLogger()
        self.logger.setLevel(log_level_attr)

        log_file_handler = logging.FileHandler(
            self.ffdc_dir_path + "collector.log"
        )
        stdout_handler = logging.StreamHandler(sys.stdout)

        self.logger.addHandler(log_file_handler)
        self.logger.addHandler(stdout_handler)

        # Turn off paramiko INFO logging
        logging.getLogger("paramiko").setLevel(logging.WARNING)

    def target_is_pingable(self):
        r"""
        Check if the target system is ping-able.

        This method checks if the target system is reachable by sending an
        ICMP echo request (ping). If the target system responds to the ping,
        the method returns True. Otherwise, it returns False.

        Returns:
            bool: True if the target system is ping-able, False otherwise.
        """
        response = os.system("ping -c 2 %s  2>&1 >/dev/null" % self.hostname)
        if response == 0:
            self.logger.info(
                "\n\t[Check] %s is ping-able.\t\t [OK]" % self.hostname
            )
            return True
        else:
            self.logger.error(
                "\n\tERROR: %s is not ping-able. FFDC collection aborted.\n"
                % self.hostname
            )
            sys.exit(-1)
        return False

    def collect_ffdc(self):
        r"""
        Initiate FFDC collection based on the requested protocol.

        This method initiates FFDC (First Failure Data Capture) collection
        based on the requested protocol (SSH,SCP, TELNET, REDFISH, IPMI).
        The method establishes a connection to the target system using the
        specified protocol and collects the required FFDC data.

        Returns:
            None
        """
        self.logger.info(
            "\n\t---- Start communicating with %s ----" % self.hostname
        )
        self.start_time = time.time()

        # Find the list of target and protocol supported.
        check_protocol_list = []
        config_dict = self.ffdc_actions

        for target_type in config_dict.keys():
            if self.target_type != target_type:
                continue

            for k, v in config_dict[target_type].items():
                if v["PROTOCOL"][0] not in check_protocol_list:
                    check_protocol_list.append(v["PROTOCOL"][0])

        self.logger.info(
            "\n\t %s protocol type: %s"
            % (self.target_type, check_protocol_list)
        )

        verified_working_protocol = self.verify_protocol(check_protocol_list)

        if verified_working_protocol:
            self.logger.info(
                "\n\t---- Completed protocol pre-requisite check ----\n"
            )

        # Verify top level directory exists for storage
        self.validate_local_store(self.location)

        if (self.remote_protocol not in verified_working_protocol) and (
            self.remote_protocol != "ALL"
        ):
            self.logger.info(
                "\n\tWorking protocol list: %s" % verified_working_protocol
            )
            self.logger.error(
                "\tERROR: Requested protocol %s is not in working protocol"
                " list.\n" % self.remote_protocol
            )
            sys.exit(-1)
        else:
            self.generate_ffdc(verified_working_protocol)

    def ssh_to_target_system(self):
        r"""
        Establish an SSH connection to the target system.

        This method establishes an SSH connection to the target system using
        the provided hostname, username, password, and SSH port. If the
        connection is successful, the method returns True. Otherwise, it logs
        an error message and returns False.

        Returns:
            bool: True if the connection is successful, False otherwise.
        """

        self.ssh_remoteclient = SSHRemoteclient(
            self.hostname, self.username, self.password, self.port_ssh
        )

        if self.ssh_remoteclient.ssh_remoteclient_login():
            self.logger.info(
                "\n\t[Check] %s SSH connection established.\t [OK]"
                % self.hostname
            )

            # Check scp connection.
            # If scp connection fails,
            # continue with FFDC generation but skip scp files to local host.
            self.ssh_remoteclient.scp_connection()
            return True
        else:
            self.logger.info(
                "\n\t[Check] %s SSH connection.\t [NOT AVAILABLE]"
                % self.hostname
            )
            return False

    def telnet_to_target_system(self):
        r"""
        Establish a Telnet connection to the target system.

        This method establishes a Telnet connection to the target system using
        the provided hostname, username, and Telnet port. If the connection is
        successful, the method returns True. Otherwise, it logs an error
        message and returns False.

        Returns:
            bool: True if the connection is successful, False otherwise.
        """
        self.telnet_remoteclient = TelnetRemoteclient(
            self.hostname, self.username, self.password
        )
        if self.telnet_remoteclient.tn_remoteclient_login():
            self.logger.info(
                "\n\t[Check] %s Telnet connection established.\t [OK]"
                % self.hostname
            )
            return True
        else:
            self.logger.info(
                "\n\t[Check] %s Telnet connection.\t [NOT AVAILABLE]"
                % self.hostname
            )
            return False

    def generate_ffdc(self, working_protocol_list):
        r"""
        Generate FFDC (First Failure Data Capture) based on the remote host
        type and working protocols.

        This method determines the actions to be performed for generating FFDC
        based on the remote host type and the list of confirmed working
        protocols. The method iterates through the available actions for the
        remote host type and checks if any of the working protocols are
        supported. If a supported protocol is found, the method executes the
        corresponding FFDC generation action.

        Parameters:
            working_protocol_list (list):  A list of confirmed working
                                           protocols to connect to the
                                           remote host.

        Returns:
            None
        """
        self.logger.info(
            "\n\t---- Executing commands on " + self.hostname + " ----"
        )
        self.logger.info(
            "\n\tWorking protocol list: %s" % working_protocol_list
        )

        config_dict = self.ffdc_actions
        for target_type in config_dict.keys():
            if self.target_type != target_type:
                continue

            self.logger.info("\n\tFFDC Path: %s " % self.ffdc_dir_path)
            global_plugin_dict["global_log_store_path"] = self.ffdc_dir_path
            self.logger.info("\tSystem Type: %s" % target_type)
            for k, v in config_dict[target_type].items():
                protocol = v["PROTOCOL"][0]

                if (
                    self.remote_protocol not in working_protocol_list
                    and self.remote_protocol != "ALL"
                ) or protocol not in working_protocol_list:
                    continue

                if protocol in working_protocol_list:
                    if protocol in ["SSH", "SCP"]:
                        self.protocol_ssh(protocol, target_type, k)
                    elif protocol == "TELNET":
                        self.protocol_telnet(target_type, k)
                    elif protocol in ["REDFISH", "IPMI", "SHELL"]:
                        self.protocol_service_execute(protocol, target_type, k)
                else:
                    self.logger.error(
                        "\n\tERROR: %s is not available for %s."
                        % (protocol, self.hostname)
                    )

        # Close network connection after collecting all files
        self.elapsed_time = time.strftime(
            "%H:%M:%S", time.gmtime(time.time() - self.start_time)
        )
        self.logger.info("\n\tTotal time taken: %s" % self.elapsed_time)
        if self.ssh_remoteclient:
            self.ssh_remoteclient.ssh_remoteclient_disconnect()
        if self.telnet_remoteclient:
            self.telnet_remoteclient.tn_remoteclient_disconnect()

    def protocol_ssh(self, protocol, target_type, sub_type):
        r"""
        Perform actions using SSH and SCP protocols.

        This method executes a set of commands using the SSH protocol to
        connect to the target system and collect FFDC data. The method takes
        the protocol, target type, and sub-type as arguments and performs the
        corresponding actions based on the provided parameters.

        Parameters:
            protocol (str):    The protocol to execute (SSH or SCP).
            target_type (str): The type group of the remote host.
            sub_type (str):    The group type of commands to execute.

        Returns:
            None
        """
        if protocol == "SCP":
            self.group_copy(self.ffdc_actions[target_type][sub_type])
        else:
            self.collect_and_copy_ffdc(
                self.ffdc_actions[target_type][sub_type]
            )

    def protocol_telnet(self, target_type, sub_type):
        r"""
        Perform actions using the Telnet protocol.

        This method executes a set of commands using the Telnet protocol to
        connect to the target system and collect FFDC data. The method takes
        the target type and sub-type as arguments and performs the
        corresponding actions based on the provided parameters.

        Parameters:
            target_type (str): The type group of the remote host.
            sub_type (str):    The group type of commands to execute.

        Returns:
            None
        """
        self.logger.info(
            "\n\t[Run] Executing commands on %s using %s"
            % (self.hostname, "TELNET")
        )
        telnet_files_saved = []
        progress_counter = 0
        list_of_commands = self.ffdc_actions[target_type][sub_type]["COMMANDS"]
        for index, each_cmd in enumerate(list_of_commands, start=0):
            command_txt, command_timeout = self.unpack_command(each_cmd)
            result = self.telnet_remoteclient.execute_command(
                command_txt, command_timeout
            )
            if result:
                try:
                    targ_file = self.ffdc_actions[target_type][sub_type][
                        "FILES"
                    ][index]
                except IndexError:
                    targ_file = command_txt
                    self.logger.warning(
                        "\n\t[WARN] Missing filename to store data from"
                        " telnet %s." % each_cmd
                    )
                    self.logger.warning(
                        "\t[WARN] Data will be stored in %s." % targ_file
                    )
                targ_file_with_path = (
                    self.ffdc_dir_path + self.ffdc_prefix + targ_file
                )
                # Creates a new file
                with open(targ_file_with_path, "w") as fp:
                    fp.write(result)
                    fp.close
                    telnet_files_saved.append(targ_file)
            progress_counter += 1
            self.print_progress(progress_counter)
        self.logger.info("\n\t[Run] Commands execution completed.\t\t [OK]")
        for file in telnet_files_saved:
            self.logger.info("\n\t\tSuccessfully save file " + file + ".")

    def protocol_service_execute(self, protocol, target_type, sub_type):
        r"""
        Perform actions for a given protocol.

        This method executes a set of commands using the specified protocol to
        connect to the target system and collect FFDC data. The method takes
        the protocol, target type, and sub-type as arguments and performs the
        corresponding actions based on the provided parameters.

        Parameters:
            protocol (str):    The protocol to execute
                               (REDFISH, IPMI, or SHELL).
            target_type (str): The type group of the remote host.
            sub_type (str):    The group type of commands to execute.

        Returns:
            None
        """
        self.logger.info(
            "\n\t[Run] Executing commands to %s using %s"
            % (self.hostname, protocol)
        )
        executed_files_saved = []
        progress_counter = 0
        list_of_cmd = self.get_command_list(
            self.ffdc_actions[target_type][sub_type]
        )
        for index, each_cmd in enumerate(list_of_cmd, start=0):
            plugin_call = False
            if isinstance(each_cmd, dict):
                if "plugin" in each_cmd:
                    # If the error is set and plugin explicitly
                    # requested to skip execution on error..
                    if global_plugin_error_dict[
                        "exit_on_error"
                    ] and self.plugin_error_check(each_cmd["plugin"]):
                        self.logger.info(
                            "\n\t[PLUGIN-ERROR] exit_on_error: %s"
                            % global_plugin_error_dict["exit_on_error"]
                        )
                        self.logger.info(
                            "\t[PLUGIN-SKIP] %s" % each_cmd["plugin"][0]
                        )
                        continue
                    plugin_call = True
                    # call the plugin
                    self.logger.info("\n\t[PLUGIN-START]")
                    result = self.execute_plugin_block(each_cmd["plugin"])
                    self.logger.info("\t[PLUGIN-END]\n")
            else:
                each_cmd = self.yaml_env_and_plugin_vars_populate(each_cmd)

            if not plugin_call:
                result = self.run_tool_cmd(each_cmd)
            if result:
                try:
                    file_name = self.get_file_list(
                        self.ffdc_actions[target_type][sub_type]
                    )[index]
                    # If file is specified as None.
                    if file_name == "None":
                        continue
                    targ_file = self.yaml_env_and_plugin_vars_populate(
                        file_name
                    )
                except IndexError:
                    targ_file = each_cmd.split("/")[-1]
                    self.logger.warning(
                        "\n\t[WARN] Missing filename to store data from %s."
                        % each_cmd
                    )
                    self.logger.warning(
                        "\t[WARN] Data will be stored in %s." % targ_file
                    )

                targ_file_with_path = (
                    self.ffdc_dir_path + self.ffdc_prefix + targ_file
                )

                # Creates a new file
                with open(targ_file_with_path, "w") as fp:
                    if isinstance(result, dict):
                        fp.write(json.dumps(result))
                    else:
                        fp.write(result)
                    fp.close
                    executed_files_saved.append(targ_file)

            progress_counter += 1
            self.print_progress(progress_counter)

        self.logger.info("\n\t[Run] Commands execution completed.\t\t [OK]")

        for file in executed_files_saved:
            self.logger.info("\n\t\tSuccessfully save file " + file + ".")

    def collect_and_copy_ffdc(
        self, ffdc_actions_for_target_type, form_filename=False
    ):
        r"""
        Send commands and collect FFDC data from the targeted system.

        This method sends a set of commands and collects FFDC data from the
        targeted system based on the provided ffdc_actions_for_target_type
        dictionary. The method also has an optional form_filename parameter,
        which, if set to True, prepends the target type to the output file
        name.

        Parameters:
            ffdc_actions_for_target_type (dict): A dictionary containing
                                                 commands and files for the
                                                 selected remote host type.
            form_filename (bool, optional):      If True, prepends the target
                                                 type to the output file name.
                                                 Defaults to False.

        Returns:
            None
        """
        # Executing commands, if any
        self.ssh_execute_ffdc_commands(
            ffdc_actions_for_target_type, form_filename
        )

        # Copying files
        if self.ssh_remoteclient.scpclient:
            self.logger.info(
                "\n\n\tCopying FFDC files from remote system %s.\n"
                % self.hostname
            )

            # Retrieving files from target system
            list_of_files = self.get_file_list(ffdc_actions_for_target_type)
            self.scp_ffdc(
                self.ffdc_dir_path,
                self.ffdc_prefix,
                form_filename,
                list_of_files,
            )
        else:
            self.logger.info(
                "\n\n\tSkip copying FFDC files from remote system %s.\n"
                % self.hostname
            )

    def get_command_list(self, ffdc_actions_for_target_type):
        r"""
        Fetch a list of commands from the configuration file.

        This method retrieves a list of commands from the
        ffdc_actions_for_target_type dictionary, which contains commands and
        files for the selected remote host type. The method returns the list
        of commands.

        Parameters:
            ffdc_actions_for_target_type (dict): A dictionary containing
                                                 commands and files for the
                                                 selected remote host type.

        Returns:
            list: A list of commands.
        """
        try:
            list_of_commands = ffdc_actions_for_target_type["COMMANDS"]
            # Update any global reserved variable name with value in dict.
            list_of_commands = self.update_vars_with_env_values(
                global_plugin_dict, list_of_commands
            )
        except KeyError:
            list_of_commands = []
        return list_of_commands

    def get_file_list(self, ffdc_actions_for_target_type):
        r"""
        Fetch a list of files from the configuration file.

        This method retrieves a list of files from the
        ffdc_actions_for_target_type dictionary, which contains commands and
        files for the selected remote host type. The method returns the list
        of files.

        Parameters:
            ffdc_actions_for_target_type (dict): A dictionary containing
                                                 commands and files for the
                                                 selected remote host type.

        Returns:
            list: A list of files.
        """
        try:
            list_of_files = ffdc_actions_for_target_type["FILES"]
        except KeyError:
            list_of_files = []
        return list_of_files

    def unpack_command(self, command):
        r"""
        Unpack a command from the configuration file, handling both dictionary
        and string inputs.

        This method takes a command from the configuration file, which can be
        either a dictionary or a string. If the input is a dictionary, the
        method extracts the command text and timeout from the dictionary.
        If the input is a string, the method assumes a default timeout of
        60 seconds.
        The method returns a tuple containing the command text and timeout.

        Parameters:
            command (dict or str): A command from the configuration file,
                                   which can be either a dictionary or a
                                   string.

        Returns:
            tuple: A tuple containing the command text and timeout.
        """
        if isinstance(command, dict):
            command_txt = next(iter(command))
            command_timeout = next(iter(command.values()))
        elif isinstance(command, str):
            command_txt = command
            # Default command timeout 60 seconds
            command_timeout = 60

        return command_txt, command_timeout

    def ssh_execute_ffdc_commands(
        self, ffdc_actions_for_target_type, form_filename=False
    ):
        r"""
        Send commands in the ffdc_config file to the targeted system using SSH.

        This method sends a set of commands and collects FFDC data from the
        targeted system using the SSH protocol. The method takes the
        ffdc_actions_for_target_type dictionary and an optional
        form_filename parameter as arguments.

        If form_filename is set to True, the method prepends the target type
        to the output file name. The method returns the output of the executed
        commands.

        It also prints the progress counter string + on the console.

        Parameters:
            ffdc_actions_for_target_type (dict): A dictionary containing
                                                 commands and files for the
                                                 selected remote host type.
            form_filename (bool, optional):      If True, prepends the target
                                                 type to the output file name.
                                                 Defaults to False.

        Returns:
            None
        """
        self.logger.info(
            "\n\t[Run] Executing commands on %s using %s"
            % (self.hostname, ffdc_actions_for_target_type["PROTOCOL"][0])
        )

        list_of_commands = self.get_command_list(ffdc_actions_for_target_type)
        # If command list is empty, returns
        if not list_of_commands:
            return

        progress_counter = 0
        for command in list_of_commands:
            command_txt, command_timeout = self.unpack_command(command)

            if form_filename:
                command_txt = str(command_txt % self.target_type)

            (
                cmd_exit_code,
                err,
                response,
            ) = self.ssh_remoteclient.execute_command(
                command_txt, command_timeout
            )

            if cmd_exit_code:
                self.logger.warning(
                    "\n\t\t[WARN] %s exits with code %s."
                    % (command_txt, str(cmd_exit_code))
                )
                self.logger.warning("\t\t[WARN] %s " % err)

            progress_counter += 1
            self.print_progress(progress_counter)

        self.logger.info("\n\t[Run] Commands execution completed.\t\t [OK]")

    def group_copy(self, ffdc_actions_for_target_type):
        r"""
        SCP a group of files (wildcard) from the remote host.

        This method copies a group of files from the remote host using the SCP
        protocol. The method takes the fdc_actions_for_target_type dictionary
        as an argument, which contains commands and files for the selected
        remote host type.

        Parameters:
            fdc_actions_for_target_type (dict): A dictionary containing
                                                commands and files for the
                                                selected remote host type.

        Returns:
            None
        """
        if self.ssh_remoteclient.scpclient:
            self.logger.info(
                "\n\tCopying files from remote system %s via SCP.\n"
                % self.hostname
            )

            list_of_commands = self.get_command_list(
                ffdc_actions_for_target_type
            )
            # If command list is empty, returns
            if not list_of_commands:
                return

            for command in list_of_commands:
                try:
                    command = self.yaml_env_and_plugin_vars_populate(command)
                except IndexError:
                    self.logger.error("\t\tInvalid command %s" % command)
                    continue

                (
                    cmd_exit_code,
                    err,
                    response,
                ) = self.ssh_remoteclient.execute_command(command)

                # If file does not exist, code take no action.
                # cmd_exit_code is ignored for this scenario.
                if response:
                    scp_result = self.ssh_remoteclient.scp_file_from_remote(
                        response.split("\n"), self.ffdc_dir_path
                    )
                    if scp_result:
                        self.logger.info(
                            "\t\tSuccessfully copied from "
                            + self.hostname
                            + ":"
                            + command
                        )
                else:
                    self.logger.info("\t\t%s has no result" % command)

        else:
            self.logger.info(
                "\n\n\tSkip copying files from remote system %s.\n"
                % self.hostname
            )

    def scp_ffdc(
        self,
        targ_dir_path,
        targ_file_prefix,
        form_filename,
        file_list=None,
        quiet=None,
    ):
        r"""
        SCP all files in the file_dict to the indicated directory on the local
        system.

        This method copies all files specified in the file_dict dictionary
        from the targeted system to the local system using the SCP protocol.
        The method takes the target directory path, target file prefix, and a
        boolean flag form_filename as required arguments.

        The file_dict argument is optional and contains the files to be copied.
        The quiet argument is also optional and, if set to True, suppresses
        the output of the SCP operation.

        Parameters:
            targ_dir_path (str):        The path of the directory to receive
                                        the files on the local system.
            targ_file_prefix (str):     Prefix which will be prepended to each
                                        target file's name.
            form_filename (bool):       If True, prepends the target type to
                                        the file names.
            file_dict (dict, optional): A dictionary containing the files to
                                        be copied. Defaults to None.
            quiet (bool, optional):     If True, suppresses the output of the
                                        SCP operation. Defaults to None.

        Returns:
            None
        """
        progress_counter = 0
        for filename in file_list:
            if form_filename:
                filename = str(filename % self.target_type)
            source_file_path = filename
            targ_file_path = (
                targ_dir_path + targ_file_prefix + filename.split("/")[-1]
            )

            # If source file name contains wild card, copy filename as is.
            if "*" in source_file_path:
                scp_result = self.ssh_remoteclient.scp_file_from_remote(
                    source_file_path, self.ffdc_dir_path
                )
            else:
                scp_result = self.ssh_remoteclient.scp_file_from_remote(
                    source_file_path, targ_file_path
                )

            if not quiet:
                if scp_result:
                    self.logger.info(
                        "\t\tSuccessfully copied from "
                        + self.hostname
                        + ":"
                        + source_file_path
                        + ".\n"
                    )
                else:
                    self.logger.info(
                        "\t\tFail to copy from "
                        + self.hostname
                        + ":"
                        + source_file_path
                        + ".\n"
                    )
            else:
                progress_counter += 1
                self.print_progress(progress_counter)

    def set_ffdc_default_store_path(self):
        r"""
        Set default values for self.ffdc_dir_path and self.ffdc_prefix.

        This method sets default values for the self.ffdc_dir_path and
        self.ffdc_prefix class variables.

        The collected FFDC files will be stored in the directory
        /self.location/hostname_timestr/, with individual files having the
        format timestr_filename where timestr is in %Y%m%d-%H%M%S.

        Returns:
            None
        """
        timestr = time.strftime("%Y%m%d-%H%M%S")
        self.ffdc_dir_path = (
            self.location + "/" + self.hostname + "_" + timestr + "/"
        )
        self.ffdc_prefix = timestr + "_"
        self.validate_local_store(self.ffdc_dir_path)

    # Need to verify local store path exists prior to instantiate this class.
    # This class method to validate log path before referencing this class.
    @classmethod
    def validate_local_store(cls, dir_path):
        r"""
        Ensure the specified directory exists to store FFDC files locally.

        This method checks if the provided dir_path exists. If the directory
        does not exist, the method creates it. The method does not return any
        value.

        Parameters:
            dir_path (str): The directory path where collected FFDC data files
                            will be stored.

        Returns:
            None
        """
        if not os.path.exists(dir_path):
            try:
                os.makedirs(dir_path, 0o755)
            except (IOError, OSError) as e:
                # PermissionError
                if e.errno == EPERM or e.errno == EACCES:
                    print(
                        "\tERROR: os.makedirs %s failed with"
                        " PermissionError.\n" % dir_path
                    )
                else:
                    print(
                        "\tERROR: os.makedirs %s failed with %s.\n"
                        % (dir_path, e.strerror)
                    )
                sys.exit(-1)

    def print_progress(self, progress):
        r"""
        Print the current activity progress.

        This method prints the current activity progress using the provided
        progress counter. The method does not return any value.

        Parameters:
            progress (int): The current activity progress counter.

        Returns:
            None
        """
        sys.stdout.write("\r\t" + "+" * progress)
        sys.stdout.flush()
        time.sleep(0.1)

    def verify_redfish(self):
        r"""
        Verify if the remote host has the Redfish service active.

        This method checks if the remote host has the Redfish service active
        by sending a GET request to the Redfish base URL /redfish/v1/.
        If the request is successful (status code 200), the method returns
        stdout output of the run else error message.

        Returns:
            str: Redfish service executed output.
        """
        redfish_parm = (
            "redfishtool -r "
            + self.hostname
            + ":"
            + self.port_https
            + " -S Always raw GET /redfish/v1/"
        )
        return self.run_tool_cmd(redfish_parm, True)

    def verify_ipmi(self):
        r"""
        Verify if the remote host has the IPMI LAN service active.

        This method checks if the remote host has the IPMI LAN service active
        by sending an IPMI "power status" command.

        If the command is successful (returns a non-empty response),
        else error message.

        Returns:
            str: IPMI LAN service executed output.
        """
        if self.target_type == "BMC":
            ipmi_parm = (
                "ipmitool -I lanplus -C 17  -U "
                + self.username
                + " -P "
                + self.password
                + " -H "
                + self.hostname
                + " -p "
                + str(self.port_ipmi)
                + " power status"
            )
        else:
            ipmi_parm = (
                "ipmitool -I lanplus  -P "
                + self.password
                + " -H "
                + self.hostname
                + " -p "
                + str(self.port_ipmi)
                + " power status"
            )

        return self.run_tool_cmd(ipmi_parm, True)

    def run_tool_cmd(self, parms_string, quiet=False):
        r"""
        Run a CLI standard tool or script with the provided command options.

        This method runs a CLI standard tool or script with the provided
        parms_string command options. If the quiet parameter is set to True,
        the method suppresses the output of the command.
        The method returns the output of the command as a string.

        Parameters:
            parms_string (str):     The command options for the CLI tool or
                                    script.
            quiet (bool, optional): If True, suppresses the output of the
                                    command. Defaults to False.

        Returns:
            str: The output of the command as a string.
        """

        result = subprocess.run(
            [parms_string],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=True,
            universal_newlines=True,
        )

        if result.stderr and not quiet:
            if self.password in parms_string:
                parms_string = parms_string.replace(self.password, "********")
            self.logger.error("\n\t\tERROR with %s " % parms_string)
            self.logger.error("\t\t" + result.stderr)

        return result.stdout

    def verify_protocol(self, protocol_list):
        r"""
        Perform a working check for the provided list of protocols.

        This method checks if the specified protocols are available on the
        remote host. The method iterates through the protocol_list and
        attempts to establish a connection using each protocol.

        If a connection is successfully established, the method append to the
        list and if any protocol fails to connect, the method ignores it.

        Parameters:
            protocol_list (list):   A list of protocols to check.

        Returns:
            list: All protocols are available list.
        """

        tmp_list = []
        if self.target_is_pingable():
            tmp_list.append("SHELL")

        for protocol in protocol_list:
            if self.remote_protocol != "ALL":
                if self.remote_protocol != protocol:
                    continue

            # Only check SSH/SCP once for both protocols
            if (
                protocol == "SSH"
                or protocol == "SCP"
                and protocol not in tmp_list
            ):
                if self.ssh_to_target_system():
                    # Add only what user asked.
                    if self.remote_protocol != "ALL":
                        tmp_list.append(self.remote_protocol)
                    else:
                        tmp_list.append("SSH")
                        tmp_list.append("SCP")

            if protocol == "TELNET":
                if self.telnet_to_target_system():
                    tmp_list.append(protocol)

            if protocol == "REDFISH":
                if self.verify_redfish():
                    tmp_list.append(protocol)
                    self.logger.info(
                        "\n\t[Check] %s Redfish Service.\t\t [OK]"
                        % self.hostname
                    )
                else:
                    self.logger.info(
                        "\n\t[Check] %s Redfish Service.\t\t [NOT AVAILABLE]"
                        % self.hostname
                    )

            if protocol == "IPMI":
                if self.verify_ipmi():
                    tmp_list.append(protocol)
                    self.logger.info(
                        "\n\t[Check] %s IPMI LAN Service.\t\t [OK]"
                        % self.hostname
                    )
                else:
                    self.logger.info(
                        "\n\t[Check] %s IPMI LAN Service.\t\t [NOT AVAILABLE]"
                        % self.hostname
                    )

        return tmp_list

    def load_env(self):
        r"""
        Load the user environment variables from a YAML file.

        This method reads the environment variables from a YAML file specified
        in the ENV_FILE environment variable. If the file is not found or
        there is an error reading the file, an exception is raised.

        The YAML file should have the following format:

        .. code-block:: yaml

            VAR_NAME: VAR_VALUE

        Where VAR_NAME is the name of the environment variable, and
        VAR_VALUE is its value.

        After loading the environment variables, they are stored in the
        self.env attribute for later use.
        """

        tmp_env_vars = {
            "hostname": self.hostname,
            "username": self.username,
            "password": self.password,
            "port_ssh": self.port_ssh,
            "port_https": self.port_https,
            "port_ipmi": self.port_ipmi,
        }

        # Updatae default Env and Dict var for both so that it can be
        # verified when referencing it throughout the code.
        for key, value in tmp_env_vars.items():
            os.environ[key] = value
            self.env_dict[key] = value

        try:
            tmp_env_dict = {}
            if self.env_vars:
                tmp_env_dict = json.loads(self.env_vars)
                # Export ENV vars default.
                for key, value in tmp_env_dict.items():
                    os.environ[key] = value
                    self.env_dict[key] = str(value)

            # Load user specified ENV config YAML.
            if self.econfig:
                with open(self.econfig, "r") as file:
                    try:
                        tmp_env_dict = yaml.load(file, Loader=yaml.SafeLoader)
                    except yaml.YAMLError as e:
                        self.logger.error(e)
                        sys.exit(-1)
                # Export ENV vars.
                for key, value in tmp_env_dict["env_params"].items():
                    os.environ[key] = str(value)
                    self.env_dict[key] = str(value)
        except json.decoder.JSONDecodeError as e:
            self.logger.error("\n\tERROR: %s " % e)
            sys.exit(-1)
        except FileNotFoundError as e:
            self.logger.error("\n\tERROR: %s " % e)
            sys.exit(-1)

        # This to mask the password from displaying on the console.
        mask_dict = self.env_dict.copy()
        for k, v in mask_dict.items():
            if k.lower().find("password") != -1:
                hidden_text = []
                hidden_text.append(v)
                password_regex = (
                    "(" + "|".join([re.escape(x) for x in hidden_text]) + ")"
                )
                mask_dict[k] = re.sub(password_regex, "********", v)

        self.logger.info(json.dumps(mask_dict, indent=8, sort_keys=False))

    def execute_plugin_block(self, plugin_cmd_list):
        r"""
        Pack the plugin commands into qualified Python string objects.

        This method processes the plugin_cmd_list argument, which is expected
        to contain a list of plugin commands read from a YAML file. The method
        iterates through the list, constructs a qualified Python string object
        for each plugin command, and returns a list of these string objects.

        Parameters:
            plugin_cmd_list (list): A list of plugin commands containing
                                    plugin names and arguments.
                                    Plugin block read from YAML
                                    [
                                     {'plugin_name':'plugin.foo_func.my_func'},
                                     {'plugin_args':[10]},
                                    ]

            Example:
                Execute and no return response
                - plugin:
                  - plugin_name: plugin.foo_func.my_func
                  - plugin_args:
                      - arg1
                      - arg2

                Execute and return a response
                - plugin:
                    - plugin_name: result = plugin.foo_func.my_func
                    - plugin_args:
                        - arg1
                        - arg2

                Execute and return multiple values response
                - plugin:
                    - plugin_name: result1,result2 = plugin.foo_func.my_func
                    - plugin_args:
                        - arg1
                        - arg2

        Returns:
            str: Execute and not response or a string value(s) responses,

        """

        # Declare a variable plugin resp that can accept any data type.
        resp: Any = ""
        args_string = ""

        try:
            idx = self.key_index_list_dict("plugin_name", plugin_cmd_list)
            # Get plugin module name
            plugin_name = plugin_cmd_list[idx]["plugin_name"]

            # Get plugin function name
            idx = self.key_index_list_dict("plugin_function", plugin_cmd_list)
            plugin_function = plugin_cmd_list[idx]["plugin_function"]

            # Equal separator means plugin function returns result.
            if " = " in plugin_function:
                # Ex. ['result', 'plugin.foo_func.my_func']
                plugin_function_args = plugin_function.split(" = ")
                # plugin func return data.
                for arg in plugin_function_args:
                    if arg == plugin_function_args[-1]:
                        plugin_function = arg
                    else:
                        plugin_resp = arg.split(",")
                        # ['result1','result2']
                        for x in plugin_resp:
                            global_plugin_list.append(x)
                            global_plugin_dict[x] = ""

            # Walk the plugin args ['arg1,'arg2']
            # If the YAML plugin statement 'plugin_args' is not declared.
            plugin_args = []
            if any("plugin_args" in d for d in plugin_cmd_list):
                idx = self.key_index_list_dict("plugin_args", plugin_cmd_list)
                if idx is not None:
                    plugin_args = plugin_cmd_list[idx].get("plugin_args", [])
                    plugin_args = self.yaml_args_populate(plugin_args)
                else:
                    plugin_args = self.yaml_args_populate([])

            plugin_args = self.update_vars_with_env_values(
                global_plugin_dict, plugin_args
            )

            """
            Example of plugin_func:
                plugin.redfish.enumerate_request(
                         "xx.xx.xx.xx:443",
                         "root",
                         "********",
                         "/redfish/v1/",
                         "json")
            """
            # For logging purpose to mask password.
            # List should be string element to join else gives TypeError
            args_string = self.print_plugin_args_string(plugin_args)

            # If user wants to debug plugins.
            self.logger.debug(
                f"\tDebug Plugin function: \n\t\t{plugin_name}."
                f"{plugin_function}{args_string}"
            )

            # For generic logging plugin info.
            self.logger.info(
                f"\tPlugin function: \n\t\t{plugin_name}."
                f"{plugin_function}()"
            )

            # Execute the plugins function with args.
            resp = execute_python_function(
                plugin_name, plugin_function, *plugin_args
            )
            self.logger.info(f"\tPlugin response = {resp}")
            # Update plugin vars dict if there is any.
            if resp != "PLUGIN_EXEC_ERROR":
                self.process_response_args_data(resp)
        except Exception as e:
            # Set the plugin error state.
            global_plugin_error_dict["exit_on_error"] = True
            self.logger.error("\tERROR: execute_plugin_block: %s" % e)
            pass

        # There is a real error executing the plugin function.
        if resp == "PLUGIN_EXEC_ERROR":
            return resp

        # Check if plugin_expects_return (int, string, list,dict etc)
        if any("plugin_expects_return" in d for d in plugin_cmd_list):
            idx = self.key_index_list_dict(
                "plugin_expects_return", plugin_cmd_list
            )
            plugin_expects = plugin_cmd_list[idx]["plugin_expects_return"]
            if plugin_expects:
                if resp:
                    if (
                        self.plugin_expect_type(plugin_expects, resp)
                        == "INVALID"
                    ):
                        self.logger.error("\tWARN: Plugin error check skipped")
                    elif not self.plugin_expect_type(plugin_expects, resp):
                        self.logger.error(
                            "\tERROR: Plugin expects return data: %s"
                            % plugin_expects
                        )
                        global_plugin_error_dict["exit_on_error"] = True
                elif not resp:
                    self.logger.error(
                        "\tERROR: Plugin func failed to return data"
                    )
                    global_plugin_error_dict["exit_on_error"] = True

        return resp

    def update_vars_with_env_values(self, ref_dict, args_list):
        r"""
        Update list elements with environment or gloable variable values.

        This method updates the list arguments in the provided list with the
        corresponding values from the reference dictionary.

        The method iterates through the dictionary and checks if each of the
        key matches an element in the list. If a match is found, the method
        replaces the key with its corresponding value in the list element. If
        the value is a string, the method replaces the key in the list element.
        If the value is not a string, the method assigns the value to the list
        element.
        The method handles exceptions and continues processing the remaining
        elements in the list.

        Example:

        Input (dict, list):
        {'global_log_store_path': 'LOG_PATH/BMC/system_20250523-000337'}
        ['ls  global_log_store_path/*.txt']

        Output(list):
            ['ls  LOG_PATH/BMC/system_20250523-000337/*.txt']

        Parameters:
            ref_dict (dict):  A dictionary containing the environment or
                              global variable values.
            args_list (list): A list of arguments to update.

        Returns:
            list: The update list with global variables values.
        """
        # Replace keys in the string with their corresponding
        # values from the dictionary.
        for key, value in ref_dict.items():
            # Iterate through the list and check if each element matched
            # exact or in the string. If matches update the plugin element
            # in the list.
            for index, element in enumerate(args_list):
                try:
                    if isinstance(element, str):
                        # If the key is not in the list element string,
                        # then continue for the next element in the list.
                        if str(key) not in str(element):
                            continue
                        if isinstance(value, str):
                            args_list[index] = element.replace(key, value)
                        else:
                            args_list[index] = ref_dict[element]
                except KeyError as e:
                    print(f"Exception {e}")
                    pass
        return args_list

    def print_plugin_args_string(self, plugin_args):
        r"""
        Generate a string representation of plugin arguments, replacing the
        password if necessary.

        This method generates a string representation of the provided plugin
        arguments, joining them with commas. If the password is present in the
        arguments, it is replaced with "********".
        The method returns the generated string. If an exception occurs during
        the process, the method logs a debug log and returns "(None)".

        Parameters:
            plugin_args (list): A list of plugin arguments.

        Returns:
            str: The generated string representation of the plugin arguments.
        """
        try:
            plugin_args_str = "(" + ", ".join(map(str, plugin_args)) + ")"
            if self.password in plugin_args_str:
                args_string = plugin_args_str.replace(
                    self.password, "********"
                )
            else:
                args_string = plugin_args_str
        except Exception as e:
            self.logger.debug("\tWARN:Print args string : %s" % e)
            return "(None)"

        return args_string

    def process_response_args_data(self, plugin_resp):
        r"""
        Parse the plugin function response and update plugin return variables.

        This method parses the response data from a plugin function and
        updates the plugin return variables accordingly. The method takes the
        plugin_resp argument, which is expected to be the response data from a
        plugin function.

        The method handles various data types (string, bytes,
        tuple, list, int, float) and updates the global global_plugin_dict
        dictionary with the parsed response data. If there is an error during
        the process, the method logs a warning and continues with the next
        plugin block execution.

        Parameters:
           plugin_resp (Any): The response data from the plugin function.

        Returns:
            None
        """
        resp_list = []
        resp_data = ""

        # There is nothing to update the plugin response.
        if len(global_plugin_list) == 0 or plugin_resp == "None":
            return

        if isinstance(plugin_resp, str):
            resp_data = plugin_resp.strip("\r\n\t")
            resp_list.append(resp_data)
        elif isinstance(plugin_resp, bytes):
            resp_data = str(plugin_resp, "UTF-8").strip("\r\n\t")
            resp_list.append(resp_data)
        elif isinstance(plugin_resp, tuple):
            if len(global_plugin_list) == 1:
                resp_list.append(list(plugin_resp))
            else:
                resp_list = list(plugin_resp)
                resp_list = [x for x in resp_list]
        elif isinstance(plugin_resp, list):
            if len(global_plugin_list) == 1:
                resp_list.append([x.strip("\r\n\t") for x in plugin_resp])
            else:
                resp_list = [x.strip("\r\n\t") for x in plugin_resp]
        elif isinstance(plugin_resp, int) or isinstance(plugin_resp, float):
            resp_list.append(plugin_resp)

        # Iterate if there is a list of plugin return vars to update.
        for idx, item in enumerate(resp_list, start=0):
            # Exit loop, done required loop.
            if idx >= len(global_plugin_list):
                break
            # Find the index of the return func in the list and
            # update the global func return dictionary.
            try:
                dict_idx = global_plugin_list[idx]
                global_plugin_dict[dict_idx] = item
            except (IndexError, ValueError) as e:
                self.logger.warn("\tWARN: process_response_args_data: %s" % e)
                pass

        # Done updating plugin dict irrespective of pass or failed,
        # clear all the list element for next plugin block execute.
        global_plugin_list.clear()

    def yaml_args_populate(self, yaml_arg_list):
        r"""
        Decode environment and plugin variables and populate the argument list.

        This method processes the yaml_arg_list argument, which is expected to
        contain a list of arguments read from a YAML file. The method iterates
        through the list, decodes environment and plugin variables, and
        returns a populated list of arguments.

        .. code-block:: yaml

          - plugin_args:
            - arg1
            - arg2

        ['${hostname}:${port_https}', '${username}', '/redfish/v1/', 'json']

        Returns the populated plugin list
            ['xx.xx.xx.xx:443', 'root', '/redfish/v1/', 'json']

        Parameters:
            yaml_arg_list (list):   A list of arguments containing environment
                                    and plugin variables.

        Returns:
            list:   A populated list of arguments with decoded environment and
                    plugin variables.
        """
        if isinstance(yaml_arg_list, list):
            populated_list = []
            for arg in yaml_arg_list:
                if isinstance(arg, (int, float)):
                    populated_list.append(arg)
                elif isinstance(arg, str):
                    arg_str = self.yaml_env_and_plugin_vars_populate(arg)
                    populated_list.append(arg_str)
                else:
                    populated_list.append(arg)

            return populated_list

    def yaml_env_and_plugin_vars_populate(self, yaml_arg_str):
        r"""
        Update environment variables and plugin variables based on the
        provided YAML argument string.

        This method processes the yaml_arg_str argument, which is expected
        to contain a string representing environment variables and plugin
        variables in the format:

        .. code-block:: yaml

            - cat ${MY_VAR}
            - ls -AX my_plugin_var

        The method parses the string, extracts the variable names, and updates
        the corresponding environment variables and plugin variables.

        Parameters:
            yaml_arg_str (str):   A string containing environment and plugin
                                  variable definitions in YAML format.

        Returns:
            str:   The updated YAML argument string with plugin variables
                   replaced.
        """

        # Parse and convert the Plugin YAML vars string to python vars
        # Example:
        #   ${my_hostname}:${port_https} -> ['my_hostname', 'port_https']
        try:
            # Example, list of matching
            # env vars ['username', 'password', 'hostname']
            # Extra escape \ for special symbols. '\$\{([^\}]+)\}' works good.
            env_var_regex = r"\$\{([^\}]+)\}"
            env_var_names_list = re.findall(env_var_regex, yaml_arg_str)

            # If the list in empty [] nothing to update.
            if not len(env_var_names_list):
                return yaml_arg_str
            for var in env_var_names_list:
                env_var = os.environ.get(var)
                if env_var:
                    env_replace = "${" + var + "}"
                    yaml_arg_str = yaml_arg_str.replace(env_replace, env_var)
        except Exception as e:
            self.logger.error("\tERROR:yaml_env_vars_populate: %s" % e)
            pass

        """
        Parse the string for plugin vars.
        Implement the logic to update environment variables based on the
        extracted variable names.
        """
        try:
            # Example, list of plugin vars env_var_names_list
            #    ['my_hostname', 'port_https']
            global_plugin_dict_keys = set(global_plugin_dict.keys())
            # Skip env var list already populated above code block list.
            plugin_var_name_list = [
                var
                for var in global_plugin_dict_keys
                if var not in env_var_names_list
            ]

            for var in plugin_var_name_list:
                plugin_var_value = global_plugin_dict[var]
                if yaml_arg_str in global_plugin_dict:
                    """
                    If this plugin var exist but empty in dict, don't replace.
                    his is either a YAML plugin statement incorrectly used or
                    user added a plugin var which is not going to be populated.
                    """
                    if isinstance(plugin_var_value, (list, dict)):
                        """
                        List data type or dict can't be replaced, use
                        directly in plugin function call.
                        """
                        global_plugin_type_list.append(var)
                    else:
                        yaml_arg_str = yaml_arg_str.replace(
                            str(var), str(plugin_var_value)
                        )
        except (IndexError, ValueError) as e:
            self.logger.error("\tERROR: yaml_plugin_vars_populate: %s" % e)
            pass

        # From ${my_hostname}:${port_https} -> ['my_hostname', 'port_https']
        # to populated values string as
        # Example:  xx.xx.xx.xx:443 and return the string
        return yaml_arg_str

    def plugin_error_check(self, plugin_dict):
        r"""
        Process plugin error dictionary and return the corresponding error
        message.

        This method checks if any dictionary in the plugin_dict list contains
        a "plugin_error" key. If such a dictionary is found, it retrieves the
        value associated with the "plugin_error" key and returns the
        corresponding error message from the global_plugin_error_dict
        attribute.

        Parameters:
            plugin_dict (list of dict): A list of dictionaries containing
                                        plugin error information.

        Returns:
           str: The error message corresponding to the "plugin_error" value,
                or None if no error is found.
        """
        if any("plugin_error" in d for d in plugin_dict):
            for d in plugin_dict:
                if "plugin_error" in d:
                    value = d["plugin_error"]
                    return global_plugin_error_dict.get(value, None)
        return None

    def key_index_list_dict(self, key, list_dict):
        r"""
        Find the index of the first dictionary in the list that contains
        the specified key.

        Parameters:
            key (str):                 The key to search for in the
                                       dictionaries.
            list_dict (list of dict):  A list of dictionaries to search
                                       through.

        Returns:
            int: The index of the first dictionary containing the key, or -1
            if no match is found.
        """
        for i, d in enumerate(list_dict):
            if key in d:
                return i
        return -1

    def plugin_expect_type(self, type, data):
        r"""
        Check if the provided data matches the expected type.

        This method checks if the data argument matches the specified type.
        It supports the following types: "int", "float", "str", "list", "dict",
        and "tuple".

        If the type is not recognized, it logs an info message and returns
        "INVALID".

        Parameters:
            type (str): The expected data type.
            data:       The data to check against the expected type.

        Returns:
            bool or str: True if the data matches the expected type, False if
                         not, or "INVALID" if the type is not recognized.
        """
        if type == "int":
            return isinstance(data, int)
        elif type == "float":
            return isinstance(data, float)
        elif type == "str":
            return isinstance(data, str)
        elif type == "list":
            return isinstance(data, list)
        elif type == "dict":
            return isinstance(data, dict)
        elif type == "tuple":
            return isinstance(data, tuple)
        else:
            self.logger.info("\tInvalid data type requested: %s" % type)
            return "INVALID"
