## @file
# This file contained the parser for define 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.
#

'''
InfDefineSectionParser
'''
##
# Import Modules
#
import re

from Library import DataType as DT
from Library import GlobalData
from Library.Parsing import MacroParser
from Library.Misc import GetSplitValueList
from Library.ParserValidate import IsValidArch
from Object.Parser.InfCommonObject import InfLineCommentObject
from Object.Parser.InfDefineObject import InfDefMember
from Parser.InfParserMisc import InfExpandMacro
from Object.Parser.InfMisc import ErrorInInf
from Logger import StringTable as ST
from Parser.InfParserMisc import InfParserSectionRoot

## __GetValidateArchList
#
#
def GetValidateArchList(LineContent):

    TempArch = ''
    ArchList = []
    ValidateAcrhPatten = re.compile(r"^\s*#\s*VALID_ARCHITECTURES\s*=\s*.*$", re.DOTALL)

    if ValidateAcrhPatten.match(LineContent):
        TempArch = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)[1]

        TempArch = GetSplitValueList(TempArch, '(', 1)[0]

        ArchList = re.split('\s+', TempArch)
        NewArchList = []
        for Arch in ArchList:
            if IsValidArch(Arch):
                NewArchList.append(Arch)

        ArchList = NewArchList

    return ArchList

class InfDefinSectionParser(InfParserSectionRoot):
    def InfDefineParser(self, SectionString, InfSectionObject, FileName, SectionComment):

        if SectionComment:
            pass
        #
        # Parser Defines section content and fill self._ContentList dict.
        #
        StillCommentFalg  = False
        HeaderComments = []
        SectionContent = ''
        ArchList       = []
        _ContentList   = []
        _ValueList     = []
        #
        # Add WORKSPACE to global Marco dict.
        #
        self.FileLocalMacros['WORKSPACE'] = GlobalData.gWORKSPACE

        for Line in SectionString:
            LineContent = Line[0]
            LineNo      = Line[1]
            TailComments   = ''
            LineComment    = None

            LineInfo       = ['', -1, '']
            LineInfo[0]    = FileName
            LineInfo[1]    = LineNo
            LineInfo[2]    = LineContent

            if LineContent.strip() == '':
                continue
            #
            # The first time encountered VALIDATE_ARCHITECHERS will be considered as support arch list.
            #
            if not ArchList:
                ArchList = GetValidateArchList(LineContent)

            #
            # Parser Comment
            #
            if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                #
                # Last line is comments, and this line go on.
                #
                if StillCommentFalg:
                    HeaderComments.append(Line)
                    SectionContent += LineContent + DT.END_OF_LINE
                    continue
                #
                # First time encounter comment
                #
                else:
                    #
                    # Clear original data
                    #
                    HeaderComments = []
                    HeaderComments.append(Line)
                    StillCommentFalg = True
                    SectionContent += LineContent + DT.END_OF_LINE
                    continue
            else:
                StillCommentFalg = False

            if len(HeaderComments) >= 1:
                LineComment = InfLineCommentObject()
                LineCommentContent = ''
                for Item in HeaderComments:
                    LineCommentContent += Item[0] + DT.END_OF_LINE
                LineComment.SetHeaderComments(LineCommentContent)

            #
            # Find Tail comment.
            #
            if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                TailComments = LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):]
                LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
                if LineComment is None:
                    LineComment = InfLineCommentObject()
                LineComment.SetTailComments(TailComments)

            #
            # Find Macro
            #
            Name, Value = MacroParser((LineContent, LineNo),
                                      FileName,
                                      DT.MODEL_META_DATA_HEADER,
                                      self.FileLocalMacros)
            if Name is not None:
                self.FileLocalMacros[Name] = Value
                continue

            #
            # Replace with [Defines] section Macro
            #
            LineContent = InfExpandMacro(LineContent,
                                         (FileName, LineContent, LineNo),
                                         self.FileLocalMacros,
                                         None, True)

            SectionContent += LineContent + DT.END_OF_LINE

            TokenList = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)
            if len(TokenList) < 2:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
                           LineInfo=LineInfo)
            _ValueList[0:len(TokenList)] = TokenList
            if not _ValueList[0]:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME,
                           LineInfo=LineInfo)
            if not _ValueList[1]:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
                           LineInfo=LineInfo)

            Name, Value = _ValueList[0], _ValueList[1]

            InfDefMemberObj = InfDefMember(Name, Value)
            if (LineComment is not None):
                InfDefMemberObj.Comments.SetHeaderComments(LineComment.GetHeaderComments())
                InfDefMemberObj.Comments.SetTailComments(LineComment.GetTailComments())

            InfDefMemberObj.CurrentLine.SetFileName(self.FullPath)
            InfDefMemberObj.CurrentLine.SetLineString(LineContent)
            InfDefMemberObj.CurrentLine.SetLineNo(LineNo)

            _ContentList.append(InfDefMemberObj)
            HeaderComments = []
            TailComments = ''

        #
        # Current Define section archs
        #
        if not ArchList:
            ArchList = ['COMMON']

        InfSectionObject.SetAllContent(SectionContent)

        InfSectionObject.SetDefines(_ContentList, Arch=ArchList)

