## @file
# Build cache intermediate result and state
#
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
from Common.caching import cached_property
import Common.EdkLogger as EdkLogger
import Common.LongFilePathOs as os
from Common.BuildToolError import *
from Common.Misc import SaveFileOnChange, PathClass
from Common.Misc import TemplateString
import sys
gIsFileMap = {}

DEP_FILE_TAIL = "# Updated \n"

class IncludesAutoGen():
    """ This class is to manage the dependent files witch are used in Makefile to support incremental build.
        1. C files:
            1. MSVS.
               cl.exe has a build option /showIncludes to display include files on stdout. Build tool captures
               that messages and generate dependency files, .deps files.
            2. CLANG and GCC
               -MMD -MF build option are used to generate dependency files by compiler. Build tool updates the
               .deps files.
        2. ASL files:
            1. Trim find out all the included files with asl specific include format and generate .trim.deps file.
            2. ASL PP use c preprocessor to find out all included files with #include format and generate a .deps file
            3. build tool updates the .deps file
        3. ASM files (.asm, .s or .nasm):
            1. Trim find out all the included files with asl specific include format and generate .trim.deps file.
            2. ASM PP use c preprocessor to find out all included files with #include format and generate a deps file
            3. build tool updates the .deps file
    """
    def __init__(self, makefile_folder, ModuleAuto):
        self.d_folder = makefile_folder
        self.makefile_folder = makefile_folder
        self.module_autogen = ModuleAuto
        self.ToolChainFamily = ModuleAuto.ToolChainFamily
        self.workspace = ModuleAuto.WorkspaceDir

    def CreateModuleDeps(self):
        SaveFileOnChange(os.path.join(self.makefile_folder,"deps.txt"),"\n".join(self.DepsCollection),False)

    def CreateDepsInclude(self):
        deps_file = {'deps_file':self.deps_files}

        MakePath = self.module_autogen.BuildOption.get('MAKE', {}).get('PATH')
        if not MakePath:
            EdkLogger.error("build", PARAMETER_MISSING, Message="No Make path available.")
        elif "nmake" in MakePath:
            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
${BEGIN}
!IF EXIST(${deps_file})
!INCLUDE ${deps_file}
!ENDIF
${END}
               ''')
        else:
            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
${BEGIN}
-include ${deps_file}
${END}
               ''')

        try:
            deps_include_str = _INCLUDE_DEPS_TEMPLATE.Replace(deps_file)
        except Exception as e:
            print(e)
        SaveFileOnChange(os.path.join(self.makefile_folder,"dependency"),deps_include_str,False)

    def CreateDepsTarget(self):
        SaveFileOnChange(os.path.join(self.makefile_folder,"deps_target"),"\n".join([item +":" for item in self.DepsCollection]),False)

    @cached_property
    def deps_files(self):
        """ Get all .deps file under module build folder. """
        deps_files = []
        for root, _, files in os.walk(self.d_folder, topdown=False):
            for name in files:
                if not name.endswith(".deps"):
                    continue
                abspath = os.path.join(root, name)
                deps_files.append(abspath)
        return deps_files

    @cached_property
    def DepsCollection(self):
        """ Collect all the dependency files list from all .deps files under a module's build folder """
        includes = set()
        targetname = [item[0].Name for item in self.TargetFileList.values()]
        for abspath in self.deps_files:
            try:
                with open(abspath,"r") as fd:
                    lines = fd.readlines()

                firstlineitems = lines[0].split(": ")
                dependency_file = firstlineitems[1].strip(" \\\n")
                dependency_file = dependency_file.strip('''"''')
                if dependency_file:
                    if os.path.normpath(dependency_file +".deps") == abspath:
                        continue
                    filename = os.path.basename(dependency_file).strip()
                    if filename not in targetname:
                        includes.add(dependency_file.strip())

                for item in lines[1:]:
                    if item == DEP_FILE_TAIL:
                        continue
                    dependency_file = item.strip(" \\\n")
                    dependency_file = dependency_file.strip('''"''')
                    if dependency_file == '':
                        continue
                    if os.path.normpath(dependency_file +".deps") == abspath:
                        continue
                    filename = os.path.basename(dependency_file).strip()
                    if filename in targetname:
                        continue
                    includes.add(dependency_file.strip())
            except Exception as e:
                EdkLogger.error("build",FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False)
                continue
        rt = sorted(list(set([item.strip(' " \\\n') for item in includes])))
        return rt

    @cached_property
    def SourceFileList(self):
        """ Get a map of module's source files name to module's source files path """
        source = {os.path.basename(item.File):item.Path for item in self.module_autogen.SourceFileList}
        middle_file = {}
        for afile in source:
            if afile.upper().endswith(".VFR"):
                middle_file.update({afile.split(".")[0]+".c":os.path.join(self.module_autogen.DebugDir,afile.split(".")[0]+".c")})
            if afile.upper().endswith((".S","ASM")):
                middle_file.update({afile.split(".")[0]+".i":os.path.join(self.module_autogen.OutputDir,afile.split(".")[0]+".i")})
            if afile.upper().endswith(".ASL"):
                middle_file.update({afile.split(".")[0]+".i":os.path.join(self.module_autogen.OutputDir,afile.split(".")[0]+".i")})
        source.update({"AutoGen.c":os.path.join(self.module_autogen.OutputDir,"AutoGen.c")})
        source.update(middle_file)
        return source

    @cached_property
    def HasNamesakeSourceFile(self):
        source_base_name = set([os.path.basename(item.File) for item in self.module_autogen.SourceFileList])
        rt = len(source_base_name) != len(self.module_autogen.SourceFileList)
        return rt
    @cached_property
    def CcPPCommandPathSet(self):
        rt = set()
        rt.add(self.module_autogen.BuildOption.get('CC',{}).get('PATH'))
        rt.add(self.module_autogen.BuildOption.get('ASLCC',{}).get('PATH'))
        rt.add(self.module_autogen.BuildOption.get('ASLPP',{}).get('PATH'))
        rt.add(self.module_autogen.BuildOption.get('VFRPP',{}).get('PATH'))
        rt.add(self.module_autogen.BuildOption.get('PP',{}).get('PATH'))
        rt.add(self.module_autogen.BuildOption.get('APP',{}).get('PATH'))
        rt.discard(None)
        return rt
    @cached_property
    def TargetFileList(self):
        """ Get a map of module's target name to a tuple of module's targets path and whose input file path """
        targets = {}
        targets["AutoGen.obj"] = (PathClass(os.path.join(self.module_autogen.OutputDir,"AutoGen.obj")),PathClass(os.path.join(self.module_autogen.DebugDir,"AutoGen.c")))
        for item in self.module_autogen.Targets.values():
            for block in item:
                targets[block.Target.Path] = (block.Target,block.Inputs[0])
        return targets

    def GetRealTarget(self,source_file_abs):
        """ Get the final target file based on source file abspath """
        source_target_map = {item[1].Path:item[0].Path for item in self.TargetFileList.values()}
        source_name_map = {item[1].File:item[0].Path for item in self.TargetFileList.values()}
        target_abs = source_target_map.get(source_file_abs)
        if target_abs is None:
            if source_file_abs.strip().endswith(".i"):
                sourcefilename = os.path.basename(source_file_abs.strip())
                for sourcefile in source_name_map:
                    if sourcefilename.split(".")[0] == sourcefile.split(".")[0]:
                        target_abs = source_name_map[sourcefile]
                        break
                else:
                    target_abs = source_file_abs
            else:
                target_abs = source_file_abs
        return target_abs

    def CreateDepsFileForMsvc(self, DepList):
        """ Generate dependency files, .deps file from /showIncludes output message """
        if not DepList:
            return
        ModuleDepDict = {}
        current_source = ""
        SourceFileAbsPathMap = self.SourceFileList
        for line in DepList:
            line = line.strip()
            if self.HasNamesakeSourceFile:
                for cc_cmd in self.CcPPCommandPathSet:
                    if cc_cmd in line:
                        if '''"'''+cc_cmd+'''"''' in line:
                            cc_options = line[len(cc_cmd)+2:].split()
                        else:
                            cc_options = line[len(cc_cmd):].split()
                        for item in cc_options:
                            if not item.startswith("/"):
                                if item.endswith(".txt") and item.startswith("@"):
                                    with open(item[1:], "r") as file:
                                        source_files = file.readlines()[0].split()
                                        SourceFileAbsPathMap = {os.path.basename(file): file for file in source_files if
                                                                os.path.exists(file)}
                                else:
                                    if os.path.exists(item):
                                        SourceFileAbsPathMap.update({os.path.basename(item): item.strip()})
                        # SourceFileAbsPathMap = {os.path.basename(item):item for item in cc_options if not item.startswith("/") and os.path.exists(item)}
            if line in SourceFileAbsPathMap:
                current_source = line
                if current_source not in ModuleDepDict:
                    ModuleDepDict[SourceFileAbsPathMap[current_source]] = []
            elif "Note: including file:" ==  line.lstrip()[:21]:
                if not current_source:
                    EdkLogger.error("build",BUILD_ERROR, "Parse /showIncludes output failed. line: %s. \n" % line, RaiseError=False)
                else:
                    ModuleDepDict[SourceFileAbsPathMap[current_source]].append(line.lstrip()[22:].strip())

        for source_abs in ModuleDepDict:
            if ModuleDepDict[source_abs]:
                target_abs = self.GetRealTarget(source_abs)
                dep_file_name = os.path.basename(source_abs) + ".deps"
                SaveFileOnChange(os.path.join(os.path.dirname(target_abs),dep_file_name)," \\\n".join([target_abs+":"] + ['''"''' + item +'''"''' for item in ModuleDepDict[source_abs]]),False)

    def UpdateDepsFileforNonMsvc(self):
        """ Update .deps files.
            1. Update target path to absolute path.
            2. Update middle target to final target.
        """

        for abspath in self.deps_files:
            if abspath.endswith(".trim.deps"):
                continue
            try:
                newcontent = []
                with open(abspath,"r") as fd:
                    lines = fd.readlines()
                if lines[-1] == DEP_FILE_TAIL:
                    continue
                firstlineitems = lines[0].strip().split(" ")

                if len(firstlineitems) > 2:
                    sourceitem = firstlineitems[1]
                else:
                    sourceitem = lines[1].strip().split(" ")[0]

                source_abs = self.SourceFileList.get(sourceitem,sourceitem)
                firstlineitems[0] = self.GetRealTarget(source_abs)
                p_target = firstlineitems
                if not p_target[0].strip().endswith(":"):
                    p_target[0] += ": "

                if len(p_target) == 2:
                    p_target[0] += lines[1]
                    newcontent.append(p_target[0])
                    newcontent.extend(lines[2:])
                else:
                    line1 = " ".join(p_target).strip()
                    line1 += "\n"
                    newcontent.append(line1)
                    newcontent.extend(lines[1:])

                newcontent.append("\n")
                newcontent.append(DEP_FILE_TAIL)
                with open(abspath,"w") as fw:
                    fw.write("".join(newcontent))
            except Exception as e:
                EdkLogger.error("build",FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False)
                continue

    def UpdateDepsFileforTrim(self):
        """ Update .deps file which generated by trim. """

        for abspath in self.deps_files:
            if not abspath.endswith(".trim.deps"):
                continue
            try:
                newcontent = []
                with open(abspath,"r") as fd:
                    lines = fd.readlines()
                if lines[-1] == DEP_FILE_TAIL:
                    continue

                source_abs = lines[0].strip().split(" ")[0]
                targetitem = self.GetRealTarget(source_abs.strip(" :"))

                targetitem += ": "
                if len(lines)>=2:
                    targetitem += lines[1]
                newcontent.append(targetitem)
                newcontent.extend(lines[2:])
                newcontent.append("\n")
                newcontent.append(DEP_FILE_TAIL)
                with open(abspath,"w") as fw:
                    fw.write("".join(newcontent))
            except Exception as e:
                EdkLogger.error("build",FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False)
                continue
