# @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._env = environment_config
            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()
        params = ['-c', self._app_config_file]
        params += ['-F', self._app_input_file_path]
        params += ['--if-changed']
        if self._env.GetValue("UNCRUSTIFY_IN_PLACE", "FALSE") == "TRUE":
            params += ['--replace', '--no-backup']
        else:
            params += ['--suffix', UncrustifyCheck.FORMATTED_FILE_EXTENSION]
        self._app_exit_code = RunCmd(
            self._app_path,
            " ".join(params),
            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.info("A file header template is not specified in the config file.")
        except FileNotFoundError:
            logging.info("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.info("A function header template is not specified in the config file.")
        except FileNotFoundError:
            logging.info("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(f'Uncrustify found {self._formatted_file_error_count} files with formatting errors\n')
            self._tc.LogStdError(f"Uncrustify found {self._formatted_file_error_count} files with formatting errors:\n")
            logging.warning(
                "Visit the following instructions to learn "
                "more about uncrustify setup instructions and CI:"
                "https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting\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(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
            self._tc.LogStdError(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")

            if (self._output_file_diffs or
                    self._file_template_contents is not None or
                    self._func_template_contents is not None):

                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):
                        logging.info(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
                        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):
                        logging.info(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
                        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):
                            logging.error(line)
                            self._tc.LogStdError(line)

                        logging.error('\n')
                        self._tc.LogStdError('\n')

    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)}")
