# @file UncrustifyCheck.py
#
# An edk2-pytool based plugin wrapper for Uncrustify
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import configparser
import difflib
import errno
import logging
import os
import pathlib
import shutil
import stat
import timeit
from edk2toolext.environment import version_aggregator
from edk2toolext.environment.plugin_manager import PluginManager
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toolext.environment.plugintypes.uefi_helper_plugin import HelperFunctions
from edk2toolext.environment.var_dict import VarDict
from edk2toollib.gitignore_parser import parse_gitignore_lines
from edk2toollib.log.junit_report_format import JunitReportTestCase
from edk2toollib.uefi.edk2.path_utilities import Edk2Path
from edk2toollib.utility_functions import  RunCmd
from io import StringIO
from typing import Any, Dict, List, Tuple

#
# Provide more user friendly messages for certain scenarios
#
class UncrustifyException(Exception):
    def __init__(self, message, exit_code):
        super().__init__(message)
        self.exit_code = exit_code


class UncrustifyAppEnvVarNotFoundException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -101)


class UncrustifyAppVersionErrorException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -102)


class UncrustifyAppExecutionException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -103)


class UncrustifyStalePluginFormattedFilesException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -120)


class UncrustifyInputFileCreationErrorException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -121)

class UncrustifyInvalidIgnoreStandardPathsException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -122)

class UncrustifyGitIgnoreFileException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -140)


class UncrustifyGitSubmoduleException(UncrustifyException):
    def __init__(self, message):
        super().__init__(message, -141)


class UncrustifyCheck(ICiBuildPlugin):
    """
    A CiBuildPlugin that uses Uncrustify to check the source files in the
    package being tested for coding standard issues.

    By default, the plugin runs against standard C source file extensions but
    its configuration can be modified through its configuration file.

    Configuration options:
    "UncrustifyCheck": {
        "AdditionalIncludePaths": [], # Additional paths to check formatting (wildcards supported).
        "AuditOnly": False,           # Don't fail the build if there are errors.  Just log them.
        "ConfigFilePath": "",         # Custom path to an Uncrustify config file.
        "IgnoreStandardPaths": [],    # Standard Plugin defined paths that should be ignored.
        "OutputFileDiffs": False,     # Output chunks of formatting diffs in the test case log.
                                      # This can significantly slow down the plugin on very large packages.
        "SkipGitExclusions": False    # Don't exclude git ignored files and files in git submodules.
    }
    """

    #
    # By default, use an "uncrustify.cfg" config file in the plugin directory
    # A package can override this path via "ConfigFilePath"
    #
    # Note: Values specified via "ConfigFilePath" are relative to the package
    #
    DEFAULT_CONFIG_FILE_PATH = os.path.join(
        pathlib.Path(__file__).parent.resolve(), "uncrustify.cfg")

    #
    # The extension used for formatted files produced by this plugin
    #
    FORMATTED_FILE_EXTENSION = ".uncrustify_plugin"

    #
    # A package can add any additional paths with "AdditionalIncludePaths"
    # A package can remove any of these paths with "IgnoreStandardPaths"
    #
    STANDARD_PLUGIN_DEFINED_PATHS = ("*.c", "*.h", "*.cpp")

    #
    # The Uncrustify application path should set in this environment variable
    #
    UNCRUSTIFY_PATH_ENV_KEY = "UNCRUSTIFY_CI_PATH"

    def GetTestName(self, packagename: str, environment: VarDict) -> Tuple:
        """ Provide the testcase name and classname for use in reporting

            Args:
              packagename: string containing name of package to build
              environment: The VarDict for the test to run in
            Returns:
                A tuple containing the testcase name and the classname
                (testcasename, classname)
                testclassname: a descriptive string for the testcase can include whitespace
                classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
        """
        return ("Check file coding standard compliance in " + packagename, packagename + ".UncrustifyCheck")

    def RunBuildPlugin(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], environment_config: Any, plugin_manager: PluginManager, plugin_manager_helper: HelperFunctions, tc: JunitReportTestCase, output_stream=None) -> int:
        """
        External function of plugin. This function is used to perform the task of the CiBuild Plugin.

        Args:
          - package_rel_path: edk2 workspace relative path to the package
          - edk2_path: Edk2Path object with workspace and packages paths
          - package_config: Dictionary with the package configuration
          - environment_config: Environment configuration
          - plugin_manager: Plugin Manager Instance
          - plugin_manager_helper: Plugin Manager Helper Instance
          - tc: JUnit test case
          - output_stream: The StringIO output stream from this plugin (logging)

        Returns
          >0 : Number of errors found
          0  : Passed successfully
          -1 : Skipped for missing prereq
        """
        try:
            # Initialize plugin and check pre-requisites.
            self._initialize_environment_info(
                package_rel_path, edk2_path, package_config, tc)
            self._initialize_configuration()
            self._check_for_preexisting_formatted_files()

            # Log important context information.
            self._log_uncrustify_app_info()

            # Get template file contents if specified
            self._get_template_file_contents()

            # Create meta input files & directories
            self._create_temp_working_directory()
            self._create_uncrustify_file_list_file()

            self._run_uncrustify()

            # Post-execution actions.
            self._process_uncrustify_results()

        except UncrustifyException as e:
            self._tc.LogStdError(
                f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
            logging.warning(
                f"Uncrustify error {e.exit_code}. Details:\n\n{str(e)}")
            return -1
        else:
            if self._formatted_file_error_count > 0:
                if self._audit_only_mode:
                    logging.info(
                        "Setting test as skipped since AuditOnly is enabled")
                    self._tc.SetSkipped()
                    return -1
                else:
                    self._tc.SetFailed(
                        f"{self._plugin_name} failed due to {self._formatted_file_error_count} incorrectly formatted files.", "CHECK_FAILED")
            else:
                self._tc.SetSuccess()
            return self._formatted_file_error_count
        finally:
            self._cleanup_temporary_formatted_files()
            self._cleanup_temporary_directory()

    def _initialize_configuration(self) -> None:
        """
        Initializes plugin configuration.
        """
        self._initialize_app_info()
        self._initialize_config_file_info()
        self._initialize_file_to_format_info()
        self._initialize_test_case_output_options()

    def _check_for_preexisting_formatted_files(self) -> None:
        """
        Checks if any formatted files from prior execution are present.

        Existence of such files is an unexpected condition. This might result
        from an error that occurred during a previous run or a premature exit from a debug scenario. In any case, the package should be clean before starting a new run.
        """
        pre_existing_formatted_file_count = len(
            [str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')])

        if pre_existing_formatted_file_count > 0:
            raise UncrustifyStalePluginFormattedFilesException(
                f"{pre_existing_formatted_file_count} formatted files already exist. To prevent overwriting these files, please remove them before running this plugin.")

    def _cleanup_temporary_directory(self) -> None:
        """
        Cleans up the temporary directory used for this execution instance.

        This removes the directory and all files created during this instance.
        """
        if hasattr(self, '_working_dir'):
            self._remove_tree(self._working_dir)

    def _cleanup_temporary_formatted_files(self) -> None:
        """
        Cleans up the temporary formmatted files produced by Uncrustify.

        This will recursively remove all formatted files generated by Uncrustify
        during this execution instance.
        """
        if hasattr(self, '_abs_package_path'):
            formatted_files = [str(path.resolve()) for path in pathlib.Path(
                self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]

            for formatted_file in formatted_files:
                os.remove(formatted_file)

    def _create_temp_working_directory(self) -> None:
        """
        Creates the temporary directory used for this execution instance.
        """
        self._working_dir = os.path.join(
            self._abs_workspace_path, "Build", ".pytool", "Plugin", f"{self._plugin_name}")

        try:
            pathlib.Path(self._working_dir).mkdir(parents=True, exist_ok=True)
        except OSError as e:
            raise UncrustifyInputFileCreationErrorException(
                f"Error creating plugin directory {self._working_dir}.\n\n{repr(e)}.")

    def _create_uncrustify_file_list_file(self) -> None:
        """
        Creates the file with the list of source files for Uncrustify to process.
        """
        self._app_input_file_path = os.path.join(
            self._working_dir, "uncrustify_file_list.txt")

        with open(self._app_input_file_path, 'w', encoding='utf8') as f:
            f.writelines(f"\n".join(self._abs_file_paths_to_format))

    def _execute_uncrustify(self) -> None:
        """
        Executes Uncrustify with the initialized configuration.
        """
        output = StringIO()
        self._app_exit_code = RunCmd(
            self._app_path,
            f"-c {self._app_config_file} -F {self._app_input_file_path} --if-changed --suffix {UncrustifyCheck.FORMATTED_FILE_EXTENSION}", outstream=output)
        self._app_output = output.getvalue().strip().splitlines()

    def _get_files_ignored_in_config(self):
        """"
        Returns a function that returns true if a given file string path is ignored in the plugin configuration file and false otherwise.
        """
        ignored_files = []
        if "IgnoreFiles" in self._package_config:
            ignored_files = self._package_config["IgnoreFiles"]

        # Pass "Package configuration file" as the source file path since
        # the actual configuration file name is unknown to this plugin and
        # this provides a generic description of the file that provided
        # the ignore file content.
        #
        # This information is only used for reporting (not used here) and
        # the ignore lines are being passed directly as they are given to
        # this plugin.
        return parse_gitignore_lines(ignored_files, "Package configuration file", self._abs_package_path)

    def _get_git_ignored_paths(self) -> List[str]:
        """"
        Returns a list of file absolute path strings to all files ignored in this git repository.

        If git is not found, an empty list will be returned.
        """
        if not shutil.which("git"):
            logging.warning(
                "Git is not found on this system. Git submodule paths will not be considered.")
            return []

        outstream_buffer = StringIO()
        exit_code = RunCmd("git", "ls-files --other",
                           workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
        if (exit_code != 0):
            raise UncrustifyGitIgnoreFileException(
                f"An error occurred reading git ignore settings. This will prevent Uncrustify from running against the expected set of files.")

        # Note: This will potentially be a large list, but at least sorted
        rel_paths = outstream_buffer.getvalue().strip().splitlines()
        abs_paths = []
        for path in rel_paths:
            abs_paths.append(
                os.path.normpath(os.path.join(self._abs_workspace_path, path)))
        return abs_paths

    def _get_git_submodule_paths(self) -> List[str]:
        """
        Returns a list of directory absolute path strings to the root of each submodule in the workspace repository.

        If git is not found, an empty list will be returned.
        """
        if not shutil.which("git"):
            logging.warning(
                "Git is not found on this system. Git submodule paths will not be considered.")
            return []

        if os.path.isfile(os.path.join(self._abs_workspace_path, ".gitmodules")):
            logging.info(
                f".gitmodules file found. Excluding submodules in {self._package_name}.")

            outstream_buffer = StringIO()
            exit_code = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self._abs_workspace_path, outstream=outstream_buffer, logging_level=logging.NOTSET)
            if (exit_code != 0):
                raise UncrustifyGitSubmoduleException(
                    f".gitmodule file detected but an error occurred reading the file. Cannot proceed with unknown submodule paths.")

            submodule_paths = []
            for line in outstream_buffer.getvalue().strip().splitlines():
                submodule_paths.append(
                    os.path.normpath(os.path.join(self._abs_workspace_path, line.split()[1])))

            return submodule_paths
        else:
            return []

    def _get_template_file_contents(self) -> None:
        """
        Gets the contents of Uncrustify template files if they are specified
        in the Uncrustify configuration file.
        """

        self._file_template_contents = None
        self._func_template_contents = None

        # Allow no value to allow "set" statements in the config file which do
        # not specify value assignment
        parser = configparser.ConfigParser(allow_no_value=True)
        with open(self._app_config_file, 'r') as cf:
            parser.read_string("[dummy_section]\n" + cf.read())

        try:
            file_template_name = parser["dummy_section"]["cmt_insert_file_header"]

            file_template_path = pathlib.Path(file_template_name)

            if not file_template_path.is_file():
                file_template_path = pathlib.Path(os.path.join(self._plugin_path, file_template_name))
                self._file_template_contents = file_template_path.read_text()
        except KeyError:
            logging.warning("A file header template is not specified in the config file.")
        except FileNotFoundError:
            logging.warning("The specified file header template file was not found.")
        try:
            func_template_name = parser["dummy_section"]["cmt_insert_func_header"]

            func_template_path = pathlib.Path(func_template_name)

            if not func_template_path.is_file():
                func_template_path = pathlib.Path(os.path.join(self._plugin_path, func_template_name))
                self._func_template_contents = func_template_path.read_text()
        except KeyError:
            logging.warning("A function header template is not specified in the config file.")
        except FileNotFoundError:
            logging.warning("The specified function header template file was not found.")

    def _initialize_app_info(self) -> None:
        """
        Initialize Uncrustify application information.

        This function will determine the application path and version.
        """
        # Verify Uncrustify is specified in the environment.
        if UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY not in os.environ:
            raise UncrustifyAppEnvVarNotFoundException(
                f"Uncrustify environment variable {UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY} is not present.")

        self._app_path = shutil.which('uncrustify', path=os.environ[UncrustifyCheck.UNCRUSTIFY_PATH_ENV_KEY])

        if self._app_path is None:
            raise FileNotFoundError(
                errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)

        self._app_path = os.path.normcase(os.path.normpath(self._app_path))

        if not os.path.isfile(self._app_path):
            raise FileNotFoundError(
                errno.ENOENT, os.strerror(errno.ENOENT), self._app_path)

        # Verify Uncrustify is present at the expected path.
        return_buffer = StringIO()
        ret = RunCmd(self._app_path, "--version", outstream=return_buffer)
        if (ret != 0):
            raise UncrustifyAppVersionErrorException(
                f"Error occurred executing --version: {ret}.")

        # Log Uncrustify version information.
        self._app_version = return_buffer.getvalue().strip()
        self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
        version_aggregator.GetVersionAggregator().ReportVersion(
            "Uncrustify", self._app_version, version_aggregator.VersionTypes.INFO)

    def _initialize_config_file_info(self) -> None:
        """
        Initialize Uncrustify configuration file info.

        The config file path is relative to the package root.
        """
        self._app_config_file = UncrustifyCheck.DEFAULT_CONFIG_FILE_PATH
        if "ConfigFilePath" in self._package_config:
            self._app_config_file = self._package_config["ConfigFilePath"].strip()

            self._app_config_file = os.path.normpath(
                os.path.join(self._abs_package_path, self._app_config_file))

        if not os.path.isfile(self._app_config_file):
            raise FileNotFoundError(
                errno.ENOENT, os.strerror(errno.ENOENT), self._app_config_file)

    def _initialize_environment_info(self, package_rel_path: str, edk2_path: Edk2Path, package_config: Dict[str, List[str]], tc: JunitReportTestCase) -> None:
        """
        Initializes plugin environment information.
        """
        self._abs_package_path = edk2_path.GetAbsolutePathOnThisSystemFromEdk2RelativePath(
            package_rel_path)
        self._abs_workspace_path = edk2_path.WorkspacePath
        self._package_config = package_config
        self._package_name = os.path.basename(
            os.path.normpath(package_rel_path))
        self._plugin_name = self.__class__.__name__
        self._plugin_path = os.path.dirname(os.path.realpath(__file__))
        self._rel_package_path = package_rel_path
        self._tc = tc

    def _initialize_file_to_format_info(self) -> None:
        """
        Forms the list of source files for Uncrustify to process.
        """
        # Create a list of all the package relative file paths in the package to run against Uncrustify.
        rel_file_paths_to_format = list(
            UncrustifyCheck.STANDARD_PLUGIN_DEFINED_PATHS)

        # Allow the ci.yaml to remove any of the pre-defined standard paths
        if "IgnoreStandardPaths" in self._package_config:
            for a in self._package_config["IgnoreStandardPaths"]:
                if a.strip() in rel_file_paths_to_format:
                    self._tc.LogStdOut(
                        f"Ignoring standard path due to ci.yaml ignore: {a}")
                    rel_file_paths_to_format.remove(a.strip())
                else:
                    raise UncrustifyInvalidIgnoreStandardPathsException(f"Invalid IgnoreStandardPaths value: {a}")

        # Allow the ci.yaml to specify additional include paths for this package
        if "AdditionalIncludePaths" in self._package_config:
            rel_file_paths_to_format.extend(
                self._package_config["AdditionalIncludePaths"])

        self._abs_file_paths_to_format = []
        for path in rel_file_paths_to_format:
            self._abs_file_paths_to_format.extend(
                [str(path.resolve()) for path in pathlib.Path(self._abs_package_path).rglob(path)])

        # Remove files ignore in the plugin configuration file
        plugin_ignored_files = list(filter(self._get_files_ignored_in_config(), self._abs_file_paths_to_format))

        if plugin_ignored_files:
            logging.info(
                f"{self._package_name} file count before plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")
            for path in plugin_ignored_files:
                if path in self._abs_file_paths_to_format:
                    logging.info(f"  File ignored in plugin config file: {path}")
                    self._abs_file_paths_to_format.remove(path)
            logging.info(
                f"{self._package_name} file count after plugin ignore file exclusion: {len(self._abs_file_paths_to_format)}")

        if not "SkipGitExclusions" in self._package_config or not self._package_config["SkipGitExclusions"]:
            # Remove files ignored by git
            logging.info(
                f"{self._package_name} file count before git ignore file exclusion: {len(self._abs_file_paths_to_format)}")

            ignored_paths = self._get_git_ignored_paths()
            self._abs_file_paths_to_format = list(
                set(self._abs_file_paths_to_format).difference(ignored_paths))

            logging.info(
                f"{self._package_name} file count after git ignore file exclusion: {len(self._abs_file_paths_to_format)}")

            # Remove files in submodules
            logging.info(
                f"{self._package_name} file count before submodule exclusion: {len(self._abs_file_paths_to_format)}")

            submodule_paths = tuple(self._get_git_submodule_paths())
            for path in submodule_paths:
                logging.info(f"  submodule path: {path}")

            self._abs_file_paths_to_format = [
                f for f in self._abs_file_paths_to_format if not f.startswith(submodule_paths)]

            logging.info(
                f"{self._package_name} file count after submodule exclusion: {len(self._abs_file_paths_to_format)}")

        # Sort the files for more consistent results
        self._abs_file_paths_to_format.sort()

    def _initialize_test_case_output_options(self) -> None:
        """
        Initializes options that influence test case output.
        """
        self._audit_only_mode = False
        self._output_file_diffs = True

        if "AuditOnly" in self._package_config and self._package_config["AuditOnly"]:
            self._audit_only_mode = True

        if "OutputFileDiffs" in self._package_config and not self._package_config["OutputFileDiffs"]:
            self._output_file_diffs = False

    def _log_uncrustify_app_info(self) -> None:
        """
        Logs Uncrustify application information.
        """
        self._tc.LogStdOut(f"Found Uncrustify at {self._app_path}")
        self._tc.LogStdOut(f"Uncrustify version: {self._app_version}")
        self._tc.LogStdOut('\n')
        logging.info(f"Found Uncrustify at {self._app_path}")
        logging.info(f"Uncrustify version: {self._app_version}")
        logging.info('\n')

    def _process_uncrustify_results(self) -> None:
        """
        Process the results from Uncrustify.

        Determines whether formatting errors are present and logs failures.
        """
        formatted_files = [str(path.resolve()) for path in pathlib.Path(
            self._abs_package_path).rglob(f'*{UncrustifyCheck.FORMATTED_FILE_EXTENSION}')]

        self._formatted_file_error_count = len(formatted_files)

        if self._formatted_file_error_count > 0:
            logging.error(
                "Visit the following instructions to learn "
                "how to find the detailed formatting errors in Azure "
                "DevOps CI: "
                "https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting#how-to-find-uncrustify-formatting-errors-in-continuous-integration-ci")
            self._tc.LogStdError("Files with formatting errors:\n")

            if self._output_file_diffs:
                logging.info("Calculating file diffs. This might take a while...")

        for formatted_file in formatted_files:
            pre_formatted_file = formatted_file[:-
                                                len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)]
            logging.error(pre_formatted_file)

            if (self._output_file_diffs or
                    self._file_template_contents is not None or
                    self._func_template_contents is not None):
                self._tc.LogStdError(
                    f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")

                with open(formatted_file) as ff:
                    formatted_file_text = ff.read()

                    if (self._file_template_contents is not None and
                            self._file_template_contents in formatted_file_text):
                        self._tc.LogStdError(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")

                    if (self._func_template_contents is not None and
                            self._func_template_contents in formatted_file_text):
                        self._tc.LogStdError(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")

                    if self._output_file_diffs:
                        with open(pre_formatted_file) as pf:
                            pre_formatted_file_text = pf.read()

                        for line in difflib.unified_diff(pre_formatted_file_text.split('\n'), formatted_file_text.split('\n'), fromfile=pre_formatted_file, tofile=formatted_file, n=3):
                            self._tc.LogStdError(line)

                        self._tc.LogStdError('\n')
            else:
                self._tc.LogStdError(pre_formatted_file)

    def _remove_tree(self, dir_path: str, ignore_errors: bool = False) -> None:
        """
        Helper for removing a directory. Over time there have been
        many private implementations of this due to reliability issues in the
        shutil implementations. To consolidate on a single function this helper is added.

        On error try to change file attributes. Also add retry logic.

        This function is temporarily borrowed from edk2toollib.utility_functions
        since the version used in edk2 is not recent enough to include the
        function.

        This function should be replaced by "RemoveTree" when it is available.

        Args:
          - dir_path: Path to directory to remove.
          - ignore_errors: Whether to ignore errors during removal
        """

        def _remove_readonly(func, path, _):
            """
            Private function to attempt to change permissions on file/folder being deleted.
            """
            os.chmod(path, stat.S_IWRITE)
            func(path)

        for _ in range(3):  # retry up to 3 times
            try:
                shutil.rmtree(dir_path, ignore_errors=ignore_errors, onerror=_remove_readonly)
            except OSError as err:
                logging.warning(f"Failed to fully remove {dir_path}: {err}")
            else:
                break
        else:
            raise RuntimeError(f"Failed to remove {dir_path}")

    def _run_uncrustify(self) -> None:
        """
        Runs Uncrustify for this instance of plugin execution.
        """
        logging.info("Executing Uncrustify. This might take a while...")
        start_time = timeit.default_timer()
        self._execute_uncrustify()
        end_time = timeit.default_timer() - start_time

        execution_summary = f"Uncrustify executed against {len(self._abs_file_paths_to_format)} files in {self._package_name} in {end_time:.2f} seconds.\n"

        self._tc.LogStdOut(execution_summary)
        logging.info(execution_summary)

        if self._app_exit_code != 0 and self._app_exit_code != 1:
            raise UncrustifyAppExecutionException(
                f"Error {str(self._app_exit_code)} returned from Uncrustify:\n\n{str(self._app_output)}")
