## @file
# This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser
#
# Copyright (c) 2011 - 2014, 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.String 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 != None:
                DefineSectionMacros[Name] = Value
                continue

        if PackageHederFlag:

            #
            # Find Macro
            #
            Name, Value = MacroParser((Line, LineNo),
                                      FileNameString,
                                      DT.MODEL_META_DATA_PACKAGE,
                                      DefineSectionMacros)
            if Name != 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 '', ''


