## @file
# This file is used to define class objects of INF file [Packages] section.
# 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.

'''
InfPackageObject
'''

from Logger import StringTable as ST
from Logger import ToolError
import Logger.Log as Logger
from Library import GlobalData

from Library.Misc import Sdict
from Library.ParserValidate import IsValidPath
from Library.ExpressionValidate import IsValidFeatureFlagExp

class InfPackageItem():
    def __init__(self,
                 PackageName = '',
                 FeatureFlagExp = '',
                 HelpString = ''):
        self.PackageName    = PackageName
        self.FeatureFlagExp = FeatureFlagExp
        self.HelpString     = HelpString
        self.SupArchList    = []

    def SetPackageName(self, PackageName):
        self.PackageName = PackageName
    def GetPackageName(self):
        return self.PackageName

    def SetFeatureFlagExp(self, FeatureFlagExp):
        self.FeatureFlagExp = FeatureFlagExp
    def GetFeatureFlagExp(self):
        return self.FeatureFlagExp

    def SetHelpString(self, HelpString):
        self.HelpString = HelpString
    def GetHelpString(self):
        return self.HelpString

    def SetSupArchList(self, SupArchList):
        self.SupArchList = SupArchList
    def GetSupArchList(self):
        return self.SupArchList


## INF package section
#
#
#
class InfPackageObject():
    def __init__(self):
        self.Packages = Sdict()
        #
        # Macro defined in this section should be only used in this section.
        #
        self.Macros         = {}

    def SetPackages(self, PackageData, Arch = None):
        IsValidFileFlag = False
        SupArchList     = []
        for ArchItem in Arch:
            #
            # Validate Arch
            #
            if (ArchItem == '' or ArchItem is None):
                ArchItem = 'COMMON'
            SupArchList.append(ArchItem)

        for PackageItem in PackageData:
            PackageItemObj = InfPackageItem()
            HelpStringObj = PackageItem[1]
            CurrentLineOfPackItem = PackageItem[2]
            PackageItem = PackageItem[0]
            if HelpStringObj is not None:
                HelpString = HelpStringObj.HeaderComments + HelpStringObj.TailComments
                PackageItemObj.SetHelpString(HelpString)
            if len(PackageItem) >= 1:
                #
                # Validate file exist/format.
                #
                if IsValidPath(PackageItem[0], ''):
                    IsValidFileFlag = True
                elif IsValidPath(PackageItem[0], GlobalData.gINF_MODULE_DIR):
                    IsValidFileFlag = True
                elif IsValidPath(PackageItem[0], GlobalData.gWORKSPACE):
                    IsValidFileFlag = True
                else:
                    Logger.Error("InfParser",
                                 ToolError.FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(PackageItem[0]),
                                 File=CurrentLineOfPackItem[2],
                                 Line=CurrentLineOfPackItem[1],
                                 ExtraData=CurrentLineOfPackItem[0])
                    return False
                if IsValidFileFlag:
                    PackageItemObj.SetPackageName(PackageItem[0])
            if len(PackageItem) == 2:
                #
                # Validate Feature Flag Express
                #
                if PackageItem[1].strip() == '':
                    Logger.Error("InfParser",
                                 ToolError.FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
                                 File=CurrentLineOfPackItem[2],
                                 Line=CurrentLineOfPackItem[1],
                                 ExtraData=CurrentLineOfPackItem[0])
                #
                # Validate FFE
                #
                FeatureFlagRtv = IsValidFeatureFlagExp(PackageItem[1].strip())
                if not FeatureFlagRtv[0]:
                    Logger.Error("InfParser",
                                 ToolError.FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
                                 File=CurrentLineOfPackItem[2],
                                 Line=CurrentLineOfPackItem[1],
                                 ExtraData=CurrentLineOfPackItem[0])

                PackageItemObj.SetFeatureFlagExp(PackageItem[1].strip())

            if len(PackageItem) > 2:
                #
                # Invalid format of Package statement
                #
                Logger.Error("InfParser",
                             ToolError.FORMAT_INVALID,
                             ST.ERR_INF_PARSER_PACKAGE_SECTION_CONTENT_ERROR,
                             File=CurrentLineOfPackItem[2],
                             Line=CurrentLineOfPackItem[1],
                             ExtraData=CurrentLineOfPackItem[0])
            PackageItemObj.SetSupArchList(SupArchList)

            #
            # Determine package file name duplicate. Follow below rule:
            #
            # A package filename must not be duplicated within a [Packages]
            # section. Package filenames may appear in multiple architectural
            # [Packages] sections. A package filename listed in an
            # architectural [Packages] section must not be listed in the common
            # architectural [Packages] section.
            #
            # NOTE: This check will not report error now.
            #
            for Item in self.Packages:
                if Item.GetPackageName() == PackageItemObj.GetPackageName():
                    ItemSupArchList = Item.GetSupArchList()
                    for ItemArch in ItemSupArchList:
                        for PackageItemObjArch in SupArchList:
                            if ItemArch == PackageItemObjArch:
                                #
                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE
                                #
                                pass
                            if ItemArch.upper() == 'COMMON' or PackageItemObjArch.upper() == 'COMMON':
                                #
                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
                                #
                                pass

            if (PackageItemObj) in self.Packages:
                PackageList = self.Packages[PackageItemObj]
                PackageList.append(PackageItemObj)
                self.Packages[PackageItemObj] = PackageList
            else:
                PackageList = []
                PackageList.append(PackageItemObj)
                self.Packages[PackageItemObj] = PackageList

        return True

    def GetPackages(self, Arch = None):
        if Arch is None:
            return self.Packages
