## @file
# This file contained the parser for sections in INF file
#
# 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.
#

'''
InfSectionParser
'''
##
# Import Modules
#
from copy import deepcopy
import re

from Library.StringUtils import GetSplitValueList
from Library.CommentParsing import ParseHeaderCommentSection
from Library.CommentParsing import ParseComment

from Library import DataType as DT

import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID

from Object.Parser.InfDefineObject import InfDefObject
from Object.Parser.InfBuildOptionObject import InfBuildOptionsObject
from Object.Parser.InfLibraryClassesObject import InfLibraryClassObject
from Object.Parser.InfPackagesObject import InfPackageObject
from Object.Parser.InfPcdObject import InfPcdObject
from Object.Parser.InfSoucesObject import InfSourcesObject
from Object.Parser.InfUserExtensionObject import InfUserExtensionObject
from Object.Parser.InfProtocolObject import InfProtocolObject
from Object.Parser.InfPpiObject import InfPpiObject
from Object.Parser.InfGuidObject import InfGuidObject
from Object.Parser.InfDepexObject import InfDepexObject
from Object.Parser.InfBinaryObject import InfBinariesObject
from Object.Parser.InfHeaderObject import InfHeaderObject
from Object.Parser.InfMisc import InfSpecialCommentObject
from Object.Parser.InfMisc import InfHobObject
from Object.Parser.InfMisc import InfBootModeObject
from Object.Parser.InfMisc import InfEventObject
from Parser.InfParserMisc import gINF_SECTION_DEF
from Parser.InfDefineSectionParser import InfDefinSectionParser
from Parser.InfBuildOptionSectionParser import InfBuildOptionSectionParser
from Parser.InfSourceSectionParser import InfSourceSectionParser
from Parser.InfLibrarySectionParser import InfLibrarySectionParser
from Parser.InfPackageSectionParser import InfPackageSectionParser
from Parser.InfGuidPpiProtocolSectionParser import InfGuidPpiProtocolSectionParser
from Parser.InfBinarySectionParser import InfBinarySectionParser
from Parser.InfPcdSectionParser import InfPcdSectionParser
from Parser.InfDepexSectionParser import InfDepexSectionParser

## GetSpecialStr2
#
# GetSpecialStr2
#
def GetSpecialStr2(ItemList, FileName, LineNo, SectionString):
    Str2 = ''
    #
    # S2 may be Platform or ModuleType
    #
    if len(ItemList) == 3:
        #
        # Except [LibraryClass], [Depex]
        # section can has more than 2 items in section header string,
        # others should report error.
        #
        if not (ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() or \
                ItemList[0].upper() == DT.TAB_DEPEX.upper() or \
                ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper()):
            if ItemList[2] != '':
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID % (SectionString),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)
        Str2 = ItemList[2]
    elif len(ItemList) == 4:
        #
        # Except [UserExtension]
        # section can has 4 items in section header string,
        # others should report error.
        #
        if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper() or ItemList[0].upper() == DT.TAB_DEPEX.upper():
            if ItemList[3] != '':
                Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
                             % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)

        if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
            Str2 = ItemList[2] + ' | ' + ItemList[3]
        else:
            Str2 = ItemList[2]

    elif len(ItemList) > 4:
        Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
                     % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)

    return Str2

## ProcessUseExtHeader
#
#
def ProcessUseExtHeader(ItemList):
    NewItemList = []
    AppendContent = ''
    CompleteFlag = False
    for Item in ItemList:
        if Item.startswith('\"') and not Item.endswith('\"'):
            AppendContent = Item
            CompleteFlag = True
        elif Item.endswith('\"') and not Item.startswith('\"'):
            #
            # Should not have an userId or IdString not starts with " before but ends with ".
            #
            if not CompleteFlag:
                return False, []
            AppendContent = AppendContent + "." + Item
            NewItemList.append(AppendContent)
            CompleteFlag = False
            AppendContent = ''
        elif Item.endswith('\"') and Item.startswith('\"'):
            #
            # Common item, not need to combine the information
            #
            NewItemList.append(Item)
        else:
            if not CompleteFlag:
                NewItemList.append(Item)
            else:
                AppendContent = AppendContent + "." + Item

    if len(NewItemList) > 4:
        return False, []

    return True, NewItemList

## GetArch
#
# GetArch
#
def GetArch(ItemList, ArchList, FileName, LineNo, SectionString):
    #
    # S1 is always Arch
    #
    if len(ItemList) > 1:
        Arch = ItemList[1]
    else:
        Arch = 'COMMON'
    ArchList.add(Arch)

    #
    # 'COMMON' must not be used with specific ARCHs at the same section
    #
    if 'COMMON' in ArchList and len(ArchList) > 1:
        Logger.Error('Parser',
                     FORMAT_INVALID,
                     ST.ERR_INF_PARSER_SECTION_ARCH_CONFLICT,
                     File=FileName,
                     Line=LineNo,
                     ExtraData=SectionString)

    return Arch, ArchList

## InfSectionParser
#
# Inherit from object
#
class InfSectionParser(InfDefinSectionParser,
                       InfBuildOptionSectionParser,
                       InfSourceSectionParser,
                       InfLibrarySectionParser,
                       InfPackageSectionParser,
                       InfGuidPpiProtocolSectionParser,
                       InfBinarySectionParser,
                       InfPcdSectionParser,
                       InfDepexSectionParser):
    #
    # Parser objects used to implement singleton
    #
    MetaFiles = {}

    ## Factory method
    #
    # One file, one parser object. This factory method makes sure that there's
    # only one object constructed for one meta file.
    #
    #   @param  Class           class object of real AutoGen class
    #                           (InfParser, DecParser or DscParser)
    #   @param  FilePath        The path of meta file
    #
    def __new__(cls, FilePath, *args, **kwargs):
        if args:
            pass
        if kwargs:
            pass
        if FilePath in cls.MetaFiles:
            return cls.MetaFiles[FilePath]
        else:
            ParserObject = super(InfSectionParser, cls).__new__(cls)
            cls.MetaFiles[FilePath] = ParserObject
            return ParserObject

    def __init__(self):
        InfDefinSectionParser.__init__(self)
        InfBuildOptionSectionParser.__init__(self)
        InfSourceSectionParser.__init__(self)
        InfLibrarySectionParser.__init__(self)
        InfPackageSectionParser.__init__(self)
        InfGuidPpiProtocolSectionParser.__init__(self)
        InfBinarySectionParser.__init__(self)
        InfPcdSectionParser.__init__(self)
        InfDepexSectionParser.__init__(self)
        #
        # Initialize all objects that an INF file will generated.
        #
        self.InfDefSection = InfDefObject()
        self.InfBuildOptionSection = InfBuildOptionsObject()
        self.InfLibraryClassSection = InfLibraryClassObject()
        self.InfPackageSection = InfPackageObject()
        self.InfPcdSection = InfPcdObject(list(self.MetaFiles.keys())[0])
        self.InfSourcesSection = InfSourcesObject()
        self.InfUserExtensionSection = InfUserExtensionObject()
        self.InfProtocolSection = InfProtocolObject()
        self.InfPpiSection = InfPpiObject()
        self.InfGuidSection = InfGuidObject()
        self.InfDepexSection = InfDepexObject()
        self.InfPeiDepexSection = InfDepexObject()
        self.InfDxeDepexSection = InfDepexObject()
        self.InfSmmDepexSection = InfDepexObject()
        self.InfBinariesSection = InfBinariesObject()
        self.InfHeader = InfHeaderObject()
        self.InfBinaryHeader = InfHeaderObject()
        self.InfSpecialCommentSection = InfSpecialCommentObject()

        #
        # A List for store define section content.
        #
        self._PcdNameList = []
        self._SectionName = ''
        self._SectionType = 0
        self.RelaPath = ''
        self.FileName = ''

    #
    # File Header content parser
    #
    def InfHeaderParser(self, Content, InfHeaderObject2, FileName, IsBinaryHeader = False):
        if IsBinaryHeader:
            (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName, True)
            if not Abstract or not Description or not Copyright or not License:
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INVALID_BINARYHEADER_FORMAT,
                             File=FileName)
        else:
            (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName)
        #
        # Not process file name now, for later usage.
        #
        if self.FileName:
            pass

        #
        # Insert Abstract, Description, CopyRight, License into header object
        #
        InfHeaderObject2.SetAbstract(Abstract)
        InfHeaderObject2.SetDescription(Description)
        InfHeaderObject2.SetCopyright(Copyright)
        InfHeaderObject2.SetLicense(License)




    ## Section header parser
    #
    #   The section header is always in following format:
    #
    #       [section_name.arch<.platform|module_type>]
    #
    # @param String    A string contained the content need to be parsed.
    #
    def SectionHeaderParser(self, SectionString, FileName, LineNo):
        _Scope = []
        _SectionName = ''
        ArchList = set()
        _ValueList = []
        _PcdNameList = [DT.TAB_INF_FIXED_PCD.upper(),
                             DT.TAB_INF_FEATURE_PCD.upper(),
                             DT.TAB_INF_PATCH_PCD.upper(),
                             DT.TAB_INF_PCD.upper(),
                             DT.TAB_INF_PCD_EX.upper()
                             ]
        SectionString = SectionString.strip()
        for Item in GetSplitValueList(SectionString[1:-1], DT.TAB_COMMA_SPLIT):
            if Item == '':
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)
            ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
            #
            # different section should not mix in one section
            # Allow different PCD type sections mixed together
            #
            if _SectionName.upper() not in _PcdNameList:
                if _SectionName != '' and _SectionName.upper() != ItemList[0].upper():
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_SECTION_NAME_DUPLICATE,
                                 File=FileName,
                                 Line=LineNo,
                                 ExtraData=SectionString)
            elif _PcdNameList[1] in [_SectionName.upper(), ItemList[0].upper()] and \
                (_SectionName.upper()!= ItemList[0].upper()):
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)

            _SectionName = ItemList[0]
            if _SectionName.upper() in gINF_SECTION_DEF:
                self._SectionType = gINF_SECTION_DEF[_SectionName.upper()]
            else:
                self._SectionType = DT.MODEL_UNKNOWN
                Logger.Error("Parser",
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_UNKNOWN_SECTION,
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)

            #
            # Get Arch
            #
            Str1, ArchList = GetArch(ItemList, ArchList, FileName, LineNo, SectionString)

            #
            # For [Defines] section, do special check.
            #
            if ItemList[0].upper() == DT.TAB_COMMON_DEFINES.upper():
                if len(ItemList) != 1:
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
                                 File=FileName, Line=LineNo, ExtraData=SectionString)

            #
            # For [UserExtension] section, do special check.
            #
            if ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():

                RetValue = ProcessUseExtHeader(ItemList)

                if not RetValue[0]:
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
                                 File=FileName, Line=LineNo, ExtraData=SectionString)
                else:
                    ItemList = RetValue[1]

                if len(ItemList) == 3:
                    ItemList.append('COMMON')

                Str1 = ItemList[1]

            #
            # For Library classes, need to check module type.
            #
            if ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() and len(ItemList) == 3:
                if ItemList[2] != '':
                    ModuleTypeList = GetSplitValueList(ItemList[2], DT.TAB_VALUE_SPLIT)
                    for Item in ModuleTypeList:
                        if Item.strip() not in DT.MODULE_LIST:
                            Logger.Error('Parser',
                                         FORMAT_INVALID,
                                         ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID % (Item),
                                         File=FileName,
                                         Line=LineNo,
                                         ExtraData=SectionString)
            #
            # GetSpecialStr2
            #
            Str2 = GetSpecialStr2(ItemList, FileName, LineNo, SectionString)

            _Scope.append([Str1, Str2])

            _NewValueList = []
            _AppendFlag = True
            if _SectionName.upper() in _PcdNameList:
                for ValueItem in _ValueList:
                    if _SectionName.upper() == ValueItem[0].upper() and Str1.upper() not in ValueItem[1].split():
                        ValueItem[1] = ValueItem[1] + " " + Str1
                        _AppendFlag = False
                    elif _SectionName.upper() == ValueItem[0].upper() and Str1.upper() in ValueItem[1].split():
                        _AppendFlag = False

                    _NewValueList.append(ValueItem)

                _ValueList = _NewValueList

            if _AppendFlag:
                if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
                    _ValueList.append([_SectionName, Str1, Str2, LineNo])
                else:
                    if len(ItemList) == 4:
                        _ValueList.append([_SectionName, Str1, Str2, ItemList[3], LineNo])

        self.SectionHeaderContent = deepcopy(_ValueList)

    ## GenSpecialSectionList
    #
    #  @param SpecialSectionList: a list of list, of which item's format
    #                             (Comment, LineNum)
    #  @param ContainerFile:      Input value for filename of Inf file
    #
    def InfSpecialCommentParser (self, SpecialSectionList, InfSectionObject, ContainerFile, SectionType):
        ReFindSpecialCommentRe = re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
        ReFindHobArchRe = re.compile(r"""[Hh][Oo][Bb]\.([^,]*)""", re.DOTALL)
        if self.FileName:
            pass
        SpecialObjectList = []
        ArchList = []
        if SectionType == DT.TYPE_EVENT_SECTION:
            TokenDict = DT.EVENT_TOKENS
        elif SectionType == DT.TYPE_HOB_SECTION:
            TokenDict = DT.HOB_TOKENS
        else:
            TokenDict = DT.BOOTMODE_TOKENS

        for List in SpecialSectionList:
            #
            # Hob has Arch attribute, need to be handled specially here
            #
            if SectionType == DT.TYPE_HOB_SECTION:

                MatchObject = ReFindSpecialCommentRe.search(List[0][0])
                HobSectionStr = MatchObject.group(1)
                ArchList = []
                for Match in ReFindHobArchRe.finditer(HobSectionStr):
                    Arch = Match.groups(1)[0].upper()
                    ArchList.append(Arch)
            CommentSoFar = ''
            for Index in range(1, len(List)):
                Result = ParseComment(List[Index], DT.ALL_USAGE_TOKENS, TokenDict, [], False)
                Usage = Result[0]
                Type = Result[1]
                HelpText = Result[3]

                if Usage == DT.ITEM_UNDEFINED and Type == DT.ITEM_UNDEFINED:
                    if HelpText is None:
                        HelpText = ''
                    if not HelpText.endswith('\n'):
                        HelpText += '\n'
                    CommentSoFar += HelpText
                else:
                    if HelpText:
                        CommentSoFar += HelpText
                    if SectionType == DT.TYPE_EVENT_SECTION:
                        SpecialObject = InfEventObject()
                        SpecialObject.SetEventType(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)
                    elif SectionType == DT.TYPE_HOB_SECTION:
                        SpecialObject = InfHobObject()
                        SpecialObject.SetHobType(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)
                        if len(ArchList) >= 1:
                            SpecialObject.SetSupArchList(ArchList)
                    else:
                        SpecialObject = InfBootModeObject()
                        SpecialObject.SetSupportedBootModes(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)

                    SpecialObjectList.append(SpecialObject)
                    CommentSoFar = ''
        if not InfSectionObject.SetSpecialComments(SpecialObjectList,
                                                   SectionType):
            Logger.Error('InfParser',
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (SectionType),
                         ContainerFile
                         )
