## @file
# This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
'''
InfAsBuiltProcess
'''
## Import modules
#

import os
import re
from Library import GlobalData
import Logger.Log as Logger
from Logger import StringTable as ST
from Logger import ToolError

from Library.StringUtils import GetSplitValueList
from Library.Misc import GetHelpStringByRemoveHashKey
from Library.Misc import ValidFile
from Library.Misc import ProcessLineExtender
from Library.ParserValidate import IsValidPath
from Library.Parsing import MacroParser
from Parser.InfParserMisc import InfExpandMacro

from Library import DataType as DT

## GetLibInstanceInfo
#
# Get the information from Library Instance INF file.
#
# @param string.  A string start with # and followed by INF file path
# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
#
# @return GUID, Version
def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName):

    FileGuidString = ""
    VerString = ""

    OrignalString = String
    String = String.strip()
    if not String:
        return None, None
    #
    # Remove "#" characters at the beginning
    #
    String = GetHelpStringByRemoveHashKey(String)
    String = String.strip()

    #
    # To deal with library instance specified by GUID and version
    #
    RegFormatGuidPattern = re.compile("\s*([0-9a-fA-F]){8}-"
                                       "([0-9a-fA-F]){4}-"
                                       "([0-9a-fA-F]){4}-"
                                       "([0-9a-fA-F]){4}-"
                                       "([0-9a-fA-F]){12}\s*")
    VersionPattern = re.compile('[\t\s]*\d+(\.\d+)?[\t\s]*')
    GuidMatchedObj = RegFormatGuidPattern.search(String)

    if String.upper().startswith('GUID') and GuidMatchedObj and 'Version' in String:
        VersionStr = String[String.upper().find('VERSION') + 8:]
        VersionMatchedObj = VersionPattern.search(VersionStr)
        if VersionMatchedObj:
            Guid = GuidMatchedObj.group().strip()
            Version = VersionMatchedObj.group().strip()
            return Guid, Version

    #
    # To deal with library instance specified by file name
    #
    FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OrignalString)


    ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
    ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")

    for Line in FileLinesList:
        if ReFindFileGuidPattern.match(Line):
            FileGuidString = Line
        if ReFindVerStringPattern.match(Line):
            VerString = Line

    if FileGuidString:
        FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
    if VerString:
        VerString = GetSplitValueList(VerString, '=', 1)[1]

    return FileGuidString, VerString

## GetPackageListInfo
#
# Get the package information from INF file.
#
# @param string.  A string start with # and followed by INF file path
# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
#
# @return GUID, Version
def GetPackageListInfo(FileNameString, WorkSpace, LineNo):
    PackageInfoList = []
    DefineSectionMacros = {}
    PackageSectionMacros = {}

    FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '')

    RePackageHeader = re.compile('^\s*\[Packages.*\].*$')
    ReDefineHeader = re.compile('^\s*\[Defines].*$')

    PackageHederFlag = False
    DefineHeaderFlag = False
    LineNo = -1
    for Line in FileLinesList:
        LineNo += 1
        Line = Line.strip()

        if Line.startswith('['):
            PackageHederFlag = False
            DefineHeaderFlag = False

        if Line.startswith("#"):
            continue

        if not Line:
            continue

        #
        # Found [Packages] section 
        #
        if RePackageHeader.match(Line):
            PackageHederFlag = True
            continue

        #
        # Found [Define] section
        #
        if ReDefineHeader.match(Line):
            DefineHeaderFlag = True
            continue

        if DefineHeaderFlag:
            #
            # Find Macro
            #
            Name, Value = MacroParser((Line, LineNo),
                                      FileNameString,
                                      DT.MODEL_META_DATA_HEADER,
                                      DefineSectionMacros)

            if Name is not None:
                DefineSectionMacros[Name] = Value
                continue

        if PackageHederFlag:

            #
            # Find Macro
            #
            Name, Value = MacroParser((Line, LineNo),
                                      FileNameString,
                                      DT.MODEL_META_DATA_PACKAGE,
                                      DefineSectionMacros)
            if Name is not None:
                PackageSectionMacros[Name] = Value
                continue

            #
            # Replace with Local section Macro and [Defines] section Macro.
            #            
            Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True)

            Line = GetSplitValueList(Line, "#", 1)[0]
            Line = GetSplitValueList(Line, "|", 1)[0]
            PackageInfoList.append(Line)

    return PackageInfoList

def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString):

    if not LineNo:
        LineNo = -1

    #
    # Validate file name exist.
    #
    FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName)))
    if not (ValidFile(FullFileName)):
        return []

    #
    # Validate file exist/format.
    #
    if not IsValidPath(FileName, WorkSpace):
        return []

    FileLinesList = []

    try:
        FullFileName = FullFileName.replace('\\', '/')
        Inputfile = open(FullFileName, "rb", 0)
        try:
            FileLinesList = Inputfile.readlines()
        except BaseException:
            Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName)
        finally:
            Inputfile.close()
    except BaseException:
        Logger.Error("InfParser",
                     ToolError.FILE_READ_FAILURE,
                     ST.ERR_FILE_OPEN_FAILURE,
                     File=FullFileName)

    FileLinesList = ProcessLineExtender(FileLinesList)

    return FileLinesList

##
# Get all INF files from current workspace
#
#
def GetInfsFromWorkSpace(WorkSpace):
    InfFiles = []
    for top, dirs, files in os.walk(WorkSpace):
        dirs = dirs # just for pylint
        for File in files:
            if File.upper().endswith(".INF"):
                InfFiles.append(os.path.join(top, File))

    return InfFiles

##
# Get GUID and version from library instance file
#
#
def GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName):
    for InfFile in GetInfsFromWorkSpace(WorkSpace):
        try:
            if InfFile.strip().upper() == CurrentInfFileName.strip().upper():
                continue
            InfFile = InfFile.replace('\\', '/')
            if InfFile not in GlobalData.gLIBINSTANCEDICT:
                InfFileObj = open(InfFile, "rb", 0)
                GlobalData.gLIBINSTANCEDICT[InfFile] = InfFileObj
            else:
                InfFileObj = GlobalData.gLIBINSTANCEDICT[InfFile]

        except BaseException:
            Logger.Error("InfParser",
                         ToolError.FILE_READ_FAILURE,
                         ST.ERR_FILE_OPEN_FAILURE,
                         File=InfFile)
        try:
            FileLinesList = InfFileObj.readlines()
            FileLinesList = ProcessLineExtender(FileLinesList)

            ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
            ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")

            for Line in FileLinesList:
                if ReFindFileGuidPattern.match(Line):
                    FileGuidString = Line
                if ReFindVerStringPattern.match(Line):
                    VerString = Line

            if FileGuidString:
                FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
            if VerString:
                VerString = GetSplitValueList(VerString, '=', 1)[1]

            if FileGuidString.strip().upper() == Guid.upper() and \
                VerString.strip().upper() == Version.upper():
                return Guid, Version

        except BaseException:
            Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=InfFile)
        finally:
            InfFileObj.close()

    return '', ''


