#!/usr/bin/env python3

r"""
This module provides valuable argument processing functions like gen_get_options and sprint_args.
"""

import os
import re
import sys

try:
    import psutil

    psutil_imported = True
except ImportError:
    psutil_imported = False
try:
    import __builtin__
except ImportError:
    import builtins as __builtin__

import argparse
import atexit
import signal
import textwrap as textwrap

import gen_cmd as gc
import gen_misc as gm
import gen_print as gp
import gen_valid as gv


class MultilineFormatter(argparse.HelpFormatter):
    def _fill_text(self, text, width, indent):
        r"""
        Split text into formatted lines for every "%%n" encountered in the text and return the result.
        """
        lines = self._whitespace_matcher.sub(" ", text).strip().split("%n")
        formatted_lines = [
            textwrap.fill(
                x, width, initial_indent=indent, subsequent_indent=indent
            )
            + "\n"
            for x in lines
        ]
        return "".join(formatted_lines)


class ArgumentDefaultsHelpMultilineFormatter(
    MultilineFormatter, argparse.ArgumentDefaultsHelpFormatter
):
    pass


default_string = '  The default value is "%(default)s".'
module = sys.modules["__main__"]


def gen_get_options(parser, stock_list=[]):
    r"""
    Parse the command line arguments using the parser object passed and return True/False (i.e. pass/fail).
    However, if gv.exit_on_error is set, simply exit the program on failure.  Also set the following built in
    values:

    __builtin__.quiet      This value is used by the qprint functions.
    __builtin__.test_mode  This value is used by command processing functions.
    __builtin__.debug      This value is used by the dprint functions.
    __builtin__.arg_obj    This value is used by print_program_header, etc.
    __builtin__.parser     This value is used by print_program_header, etc.

    Description of arguments:
    parser                          A parser object.  See argparse module documentation for details.
    stock_list                      The caller can use this parameter to request certain stock parameters
                                    offered by this function.  For example, this function will define a
                                    "quiet" option upon request.  This includes stop help text and parm
                                    checking.  The stock_list is a list of tuples each of which consists of
                                    an arg_name and a default value.  Example: stock_list = [("test_mode",
                                    0), ("quiet", 1), ("debug", 0)]
    """

    # This is a list of stock parms that we support.
    master_stock_list = ["quiet", "test_mode", "debug", "loglevel"]

    # Process stock_list.
    for ix in range(0, len(stock_list)):
        if len(stock_list[ix]) < 1:
            error_message = (
                "Programmer error - stock_list["
                + str(ix)
                + "] is supposed to be a tuple containing at"
                + " least one element which is the name of"
                + " the desired stock parameter:\n"
                + gp.sprint_var(stock_list)
            )
            return gv.process_error_message(error_message)
        if isinstance(stock_list[ix], tuple):
            arg_name = stock_list[ix][0]
            default = stock_list[ix][1]
        else:
            arg_name = stock_list[ix]
            default = None

        if arg_name not in master_stock_list:
            error_message = (
                'Programmer error - arg_name "'
                + arg_name
                + '" not found found in stock list:\n'
                + gp.sprint_var(master_stock_list)
            )
            return gv.process_error_message(error_message)

        if arg_name == "quiet":
            if default is None:
                default = 0
            parser.add_argument(
                "--quiet",
                default=default,
                type=int,
                choices=[1, 0],
                help='If this parameter is set to "1", %(prog)s'
                + " will print only essential information, i.e. it will"
                + " not echo parameters, echo commands, print the total"
                + " run time, etc."
                + default_string,
            )
        elif arg_name == "test_mode":
            if default is None:
                default = 0
            parser.add_argument(
                "--test_mode",
                default=default,
                type=int,
                choices=[1, 0],
                help="This means that %(prog)s should go through all the"
                + " motions but not actually do anything substantial."
                + "  This is mainly to be used by the developer of"
                + " %(prog)s."
                + default_string,
            )
        elif arg_name == "debug":
            if default is None:
                default = 0
            parser.add_argument(
                "--debug",
                default=default,
                type=int,
                choices=[1, 0],
                help='If this parameter is set to "1", %(prog)s will print'
                + " additional debug information.  This is mainly to be"
                + " used by the developer of %(prog)s."
                + default_string,
            )
        elif arg_name == "loglevel":
            if default is None:
                default = "info"
            parser.add_argument(
                "--loglevel",
                default=default,
                type=str,
                choices=[
                    "DEBUG",
                    "INFO",
                    "WARNING",
                    "ERROR",
                    "CRITICAL",
                    "debug",
                    "info",
                    "warning",
                    "error",
                    "critical",
                ],
                help='If this parameter is set to "1", %(prog)s will print'
                + " additional debug information.  This is mainly to be"
                + " used by the developer of %(prog)s."
                + default_string,
            )

    arg_obj = parser.parse_args()

    __builtin__.quiet = 0
    __builtin__.test_mode = 0
    __builtin__.debug = 0
    __builtin__.loglevel = "WARNING"
    for ix in range(0, len(stock_list)):
        if isinstance(stock_list[ix], tuple):
            arg_name = stock_list[ix][0]
            default = stock_list[ix][1]
        else:
            arg_name = stock_list[ix]
            default = None
        if arg_name == "quiet":
            __builtin__.quiet = arg_obj.quiet
        elif arg_name == "test_mode":
            __builtin__.test_mode = arg_obj.test_mode
        elif arg_name == "debug":
            __builtin__.debug = arg_obj.debug
        elif arg_name == "loglevel":
            __builtin__.loglevel = arg_obj.loglevel

    __builtin__.arg_obj = arg_obj
    __builtin__.parser = parser

    # For each command line parameter, create a corresponding global variable and assign it the appropriate
    # value.  For example, if the command line contained "--last_name='Smith', we'll create a global variable
    # named "last_name" with the value "Smith".
    module = sys.modules["__main__"]
    for key in arg_obj.__dict__:
        setattr(module, key, getattr(__builtin__.arg_obj, key))

    return True


def set_pgm_arg(var_value, var_name=None):
    r"""
    Set the value of the arg_obj.__dict__ entry named in var_name with the var_value provided.  Also, set
    corresponding global variable.

    Description of arguments:
    var_value                       The value to set in the variable.
    var_name                        The name of the variable to set.  This defaults to the name of the
                                    variable used for var_value when calling this function.
    """

    if var_name is None:
        var_name = gp.get_arg_name(None, 1, 2)

    arg_obj.__dict__[var_name] = var_value
    module = sys.modules["__main__"]
    setattr(module, var_name, var_value)
    if var_name == "quiet":
        __builtin__.quiet = var_value
    elif var_name == "debug":
        __builtin__.debug = var_value
    elif var_name == "test_mode":
        __builtin__.test_mode = var_value


def sprint_args(arg_obj, indent=0):
    r"""
    sprint_var all of the arguments found in arg_obj and return the result as a string.

    Description of arguments:
    arg_obj                         An argument object such as is returned by the argparse parse_args()
                                    method.
    indent                          The number of spaces to indent each line of output.
    """

    col1_width = gp.dft_col1_width + indent

    buffer = ""
    for key in arg_obj.__dict__:
        buffer += gp.sprint_varx(
            key, getattr(arg_obj, key), 0, indent, col1_width
        )
    return buffer


def sync_args():
    r"""
    Synchronize the argument values to match their corresponding global variable values.

    The user's validate_parms() function may manipulate global variables that correspond to program
    arguments.  After validate_parms() is called, sync_args is called to set the altered values back into the
    arg_obj.  This will ensure that the print-out of program arguments reflects the updated values.

    Example:

    def validate_parms():

        # Set a default value for dir_path argument.
        dir_path = gm.add_trailing_slash(gm.dft(dir_path, os.getcwd()))
    """
    module = sys.modules["__main__"]
    for key in arg_obj.__dict__:
        arg_obj.__dict__[key] = getattr(module, key)


term_options = None


def set_term_options(**kwargs):
    r"""
    Set the global term_options.

    If the global term_options is not None, gen_exit_function() will call terminate_descendants().

    Description of arguments():
    kwargs                          Supported keyword options follow:
        term_requests               Requests to terminate specified descendants of this program.  The
                                    following values for term_requests are supported:
            children                Terminate the direct children of this program.
            descendants             Terminate all descendants of this program.
            <dictionary>            A dictionary with support for the following keys:
                pgm_names           A list of program names which will be used to identify which descendant
                                    processes should be terminated.
    """

    global term_options
    # Validation:
    arg_names = list(kwargs.keys())
    gv.valid_list(arg_names, ["term_requests"])
    if type(kwargs["term_requests"]) is dict:
        keys = list(kwargs["term_requests"].keys())
        gv.valid_list(keys, ["pgm_names"])
    else:
        gv.valid_value(kwargs["term_requests"], ["children", "descendants"])
    term_options = kwargs


if psutil_imported:

    def match_process_by_pgm_name(process, pgm_name):
        r"""
        Return True or False to indicate whether the process matches the program name.

        Description of argument(s):
        process                     A psutil process object such as the one returned by psutil.Process().
        pgm_name                    The name of a program to look for in the cmdline field of the process
                                    object.
        """

        # This function will examine elements 0 and 1 of the cmdline field of the process object.  The
        # following examples will illustrate the reasons for this:

        # Example 1: Suppose a process was started like this:

        # shell_cmd('python_pgm_template --quiet=0', fork=1)

        # And then this function is called as follows:

        # match_process_by_pgm_name(process, "python_pgm_template")

        # The process object might contain the following for its cmdline field:

        # cmdline:
        #   [0]:                       /usr/bin/python
        #   [1]:                       /my_path/python_pgm_template
        #   [2]:                       --quiet=0

        # Because "python_pgm_template" is a python program, the python interpreter (e.g. "/usr/bin/python")
        # will appear in entry 0 of cmdline and the python_pgm_template will appear in entry 1 (with a
        # qualifying dir path).

        # Example 2: Suppose a process was started like this:

        # shell_cmd('sleep 5', fork=1)

        # And then this function is called as follows:

        # match_process_by_pgm_name(process, "sleep")

        # The process object might contain the following for its cmdline field:

        # cmdline:
        #   [0]:                       sleep
        #   [1]:                       5

        # Because "sleep" is a compiled executable, it will appear in entry 0.

        optional_dir_path_regex = "(.*/)?"
        cmdline = process.as_dict()["cmdline"]
        return re.match(
            optional_dir_path_regex + pgm_name + "( |$)", cmdline[0]
        ) or re.match(optional_dir_path_regex + pgm_name + "( |$)", cmdline[1])

    def select_processes_by_pgm_name(processes, pgm_name):
        r"""
        Select the processes that match pgm_name and return the result as a list of process objects.

        Description of argument(s):
        processes                   A list of psutil process objects such as the one returned by
                                    psutil.Process().
        pgm_name                    The name of a program to look for in the cmdline field of each process
                                    object.
        """

        return [
            process
            for process in processes
            if match_process_by_pgm_name(process, pgm_name)
        ]

    def sprint_process_report(pids):
        r"""
        Create a process report for the given pids and return it as a string.

        Description of argument(s):
        pids                        A list of process IDs for processes to be included in the report.
        """
        report = "\n"
        cmd_buf = (
            "echo ; ps wwo user,pgrp,pid,ppid,lstart,cmd --forest "
            + " ".join(pids)
        )
        report += gp.sprint_issuing(cmd_buf)
        rc, outbuf = gc.shell_cmd(cmd_buf, quiet=1)
        report += outbuf + "\n"

        return report

    def get_descendant_info(process=psutil.Process()):
        r"""
        Get info about the descendants of the given process and return as a tuple of descendants,
        descendant_pids and process_report.

        descendants will be a list of process objects.  descendant_pids will be a list of pids (in str form)
        and process_report will be a report produced by a call to sprint_process_report().

        Description of argument(s):
        process                     A psutil process object such as the one returned by psutil.Process().
        """
        descendants = process.children(recursive=True)
        descendant_pids = [str(process.pid) for process in descendants]
        if descendants:
            process_report = sprint_process_report(
                [str(process.pid)] + descendant_pids
            )
        else:
            process_report = ""
        return descendants, descendant_pids, process_report

    def terminate_descendants():
        r"""
        Terminate descendants of the current process according to the requirements layed out in global
        term_options variable.

        Note: If term_options is not null, gen_exit_function() will automatically call this function.

        When this function gets called, descendant processes may be running and may be printing to the same
        stdout stream being used by this process.  If this function writes directly to stdout, its output can
        be interspersed with any output generated by descendant processes.  This makes it very difficult to
        interpret the output.  In order solve this problem, the activity of this process will be logged to a
        temporary file.  After descendant processes have been terminated successfully, the temporary file
        will be printed to stdout and then deleted.  However, if this function should fail to complete (i.e.
        get hung waiting for descendants to terminate gracefully), the temporary file will not be deleted and
        can be used by the developer for debugging.  If no descendant processes are found, this function will
        return before creating the temporary file.

        Note that a general principal being observed here is that each process is responsible for the
        children it produces.
        """

        message = (
            "\n" + gp.sprint_dashes(width=120) + gp.sprint_executing() + "\n"
        )

        current_process = psutil.Process()

        descendants, descendant_pids, process_report = get_descendant_info(
            current_process
        )
        if not descendants:
            # If there are no descendants, then we have nothing to do.
            return

        terminate_descendants_temp_file_path = gm.create_temp_file_path()
        gp.print_vars(terminate_descendants_temp_file_path)

        message += (
            gp.sprint_varx("pgm_name", gp.pgm_name)
            + gp.sprint_vars(term_options)
            + process_report
        )

        # Process the termination requests:
        if term_options["term_requests"] == "children":
            term_processes = current_process.children(recursive=False)
            term_pids = [str(process.pid) for process in term_processes]
        elif term_options["term_requests"] == "descendants":
            term_processes = descendants
            term_pids = descendant_pids
        else:
            # Process term requests by pgm_names.
            term_processes = []
            for pgm_name in term_options["term_requests"]["pgm_names"]:
                term_processes.extend(
                    select_processes_by_pgm_name(descendants, pgm_name)
                )
            term_pids = [str(process.pid) for process in term_processes]

        message += gp.sprint_timen(
            "Processes to be terminated:"
        ) + gp.sprint_var(term_pids)
        for process in term_processes:
            process.terminate()
        message += gp.sprint_timen(
            "Waiting on the following pids: " + " ".join(descendant_pids)
        )
        gm.append_file(terminate_descendants_temp_file_path, message)
        psutil.wait_procs(descendants)

        # Checking after the fact to see whether any descendant processes are still alive.  If so, a process
        # report showing this will be included in the output.
        descendants, descendant_pids, process_report = get_descendant_info(
            current_process
        )
        if descendants:
            message = (
                "\n"
                + gp.sprint_timen("Not all of the processes terminated:")
                + process_report
            )
            gm.append_file(terminate_descendants_temp_file_path, message)

        message = gp.sprint_dashes(width=120)
        gm.append_file(terminate_descendants_temp_file_path, message)
        gp.print_file(terminate_descendants_temp_file_path)
        os.remove(terminate_descendants_temp_file_path)


def gen_exit_function():
    r"""
    Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT).
    """

    # ignore_err influences the way shell_cmd processes errors.  Since we're doing exit processing, we don't
    # want to stop the program due to a shell_cmd failure.
    ignore_err = 1

    if psutil_imported and term_options:
        terminate_descendants()

    # Call the main module's exit_function if it is defined.
    exit_function = getattr(module, "exit_function", None)
    if exit_function:
        exit_function()

    gp.qprint_pgm_footer()


def gen_signal_handler(signal_number, frame):
    r"""
    Handle signals.  Without a function to catch a SIGTERM or SIGINT, the program would terminate immediately
    with return code 143 and without calling the exit_function.
    """

    # The convention is to set up exit_function with atexit.register() so there is no need to explicitly
    # call exit_function from here.

    gp.qprint_executing()

    # Calling exit prevents control from returning to the code that was running when the signal was received.
    exit(0)


def gen_post_validation(exit_function=None, signal_handler=None):
    r"""
    Do generic post-validation processing.  By "post", we mean that this is to be called from a validation
    function after the caller has done any validation desired.  If the calling program passes exit_function
    and signal_handler parms, this function will register them.  In other words, it will make the
    signal_handler functions get called for SIGINT and SIGTERM and will make the exit_function function run
    prior to the termination of the program.

    Description of arguments:
    exit_function                   A function object pointing to the caller's exit function.  This defaults
                                    to this module's gen_exit_function.
    signal_handler                  A function object pointing to the caller's signal_handler function.  This
                                    defaults to this module's gen_signal_handler.
    """

    # Get defaults.
    exit_function = exit_function or gen_exit_function
    signal_handler = signal_handler or gen_signal_handler

    atexit.register(exit_function)
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)


def gen_setup():
    r"""
    Do general setup for a program.
    """

    # Set exit_on_error for gen_valid functions.
    gv.set_exit_on_error(True)

    # Get main module variable values.
    parser = getattr(module, "parser")
    stock_list = getattr(module, "stock_list")
    validate_parms = getattr(module, "validate_parms", None)

    gen_get_options(parser, stock_list)

    if validate_parms:
        validate_parms()
        sync_args()
    gen_post_validation()

    gp.qprint_pgm_header()
