# @file dependency_check.py
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##

import logging
import os
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
from edk2toolext.environment.var_dict import VarDict


class DependencyCheck(ICiBuildPlugin):
    """
    A CiBuildPlugin that finds all modules (inf files) in a package and reviews the packages used
    to confirm they are acceptable.  This is to help enforce layering and identify improper
    dependencies between packages.

    Configuration options:
    "DependencyCheck": {
        "AcceptableDependencies": [], # Package dec files that are allowed in all INFs.  Example: MdePkg/MdePkg.dec
        "AcceptableDependencies-<MODULE_TYPE>": [], # OPTIONAL Package dependencies for INFs that are HOST_APPLICATION
        "AcceptableDependencies-HOST_APPLICATION": [], # EXAMPLE Package dependencies for INFs that are HOST_APPLICATION
        "IgnoreInf": []  # Ignore INF if found in filesystem
    }
    """

    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 ("Test Package Dependencies for modules in " + packagename, packagename + ".DependencyCheck")

    ##
    # External function of plugin.  This function is used to perform the task of the MuBuild Plugin
    #
    #   - package is the edk2 path to package.  This means workspace/packagepath relative.
    #   - edk2path object configured with workspace and packages path
    #   - PkgConfig Object (dict) for the pkg
    #   - EnvConfig Object
    #   - Plugin Manager Instance
    #   - Plugin Helper Obj Instance
    #   - Junit Logger
    #   - output_stream the StringIO output stream from this plugin via logging
    def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
        overall_status = 0

        # Get current platform
        abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename)

        # Get INF Files
        INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
        INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles]  # make edk2relative path so can compare with Ignore List

        # Remove ignored INFs
        if "IgnoreInf" in pkgconfig:
            for a in pkgconfig["IgnoreInf"]:
                a = a.replace(os.sep, "/")  ## convert path sep in case ignore list is bad.  Can't change case
                try:
                    INFFiles.remove(a)
                    tc.LogStdOut("IgnoreInf {0}".format(a))
                except:
                    logging.info("DependencyConfig.IgnoreInf -> {0} not found in filesystem.  Invalid ignore file".format(a))
                    tc.LogStdError("DependencyConfig.IgnoreInf -> {0} not found in filesystem.  Invalid ignore file".format(a))


        # Get the AccpetableDependencies list
        if "AcceptableDependencies" not in pkgconfig:
            logging.info("DependencyCheck Skipped.  No Acceptable Dependencies defined.")
            tc.LogStdOut("DependencyCheck Skipped.  No Acceptable Dependencies defined.")
            tc.SetSkipped()
            return -1

        # Log dependencies
        for k in pkgconfig.keys():
            if k.startswith("AcceptableDependencies"):
                pkgstring = "\n".join(pkgconfig[k])
                if ("-" in k):
                    _, _, mod_type = k.partition("-")
                    tc.LogStdOut(f"Additional dependencies for MODULE_TYPE {mod_type}:\n {pkgstring}")
                else:
                    tc.LogStdOut(f"Acceptable Dependencies:\n {pkgstring}")

        # For each INF file
        for file in INFFiles:
            ip = InfParser()
            logging.debug("Parsing " + file)
            ip.SetBaseAbsPath(Edk2pathObj.WorkspacePath).SetPackagePaths(Edk2pathObj.PackagePathList).ParseFile(file)

            if("MODULE_TYPE" not in ip.Dict):
                tc.LogStdOut("Ignoring INF. Missing key for MODULE_TYPE {0}".format(file))
                continue

            mod_type = ip.Dict["MODULE_TYPE"].upper()
            for p in ip.PackagesUsed:
                if p not in pkgconfig["AcceptableDependencies"]:
                    # If not in the main acceptable dependencies list then check module specific
                    mod_specific_key = "AcceptableDependencies-" + mod_type
                    if mod_specific_key in pkgconfig and p in pkgconfig[mod_specific_key]:
                        continue

                    logging.error("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p))
                    tc.LogStdError("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p))
                    overall_status += 1

        # If XML object exists, add results
        if overall_status != 0:
            tc.SetFailed("Failed with {0} errors".format(overall_status), "DEPENDENCYCHECK_FAILED")
        else:
            tc.SetSuccess()
        return overall_status
