## @file
# process OptionROM generation
#
#  Copyright (c) 2007 - 2017, 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.
#

##
# Import Modules
#
import Common.LongFilePathOs as os
import subprocess

import OptRomInfStatement
from GenFdsGlobalVariable import GenFdsGlobalVariable
from GenFds import GenFds
from CommonDataClass.FdfClass import OptionRomClassObject
from Common.Misc import SaveFileOnChange
from Common import EdkLogger
from Common.BuildToolError import *

T_CHAR_LF = '\n'

## 
#
#
class OPTIONROM (OptionRomClassObject):
    ## The constructor
    #
    #   @param  self        The object pointer
    #
    def __init__(self):
        OptionRomClassObject.__init__(self)


    ## AddToBuffer()
    #
    #   Generate Option ROM
    #
    #   @param  self        The object pointer
    #   @param  Buffer      The buffer generated OptROM data will be put
    #   @retval string      Generated OptROM file path
    #
    def AddToBuffer (self, Buffer, Flag=False) :
        if not Flag:
            GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)

        EfiFileList = []
        BinFileList = []

        # Process Modules in FfsList
        for FfsFile in self.FfsList :
            
            if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement):
                FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag)
                if len(FilePathNameList) == 0:
                    EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName))
                if FfsFile.OverrideAttribs is None:
                    EfiFileList.extend(FilePathNameList)
                else:
                    FileName = os.path.basename(FilePathNameList[0])
                    TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
                    if not os.path.exists(TmpOutputDir) :
                        os.makedirs(TmpOutputDir)
                    TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
                    
                    GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, 
                                                           FilePathNameList, 
                                                           [], 
                                                           FfsFile.OverrideAttribs.NeedCompress, 
                                                           FfsFile.OverrideAttribs.PciClassCode, 
                                                           FfsFile.OverrideAttribs.PciRevision, 
                                                           FfsFile.OverrideAttribs.PciDeviceId, 
                                                           FfsFile.OverrideAttribs.PciVendorId,
                                                           IsMakefile = Flag)
                    BinFileList.append(TmpOutputFile)
            else:
                FilePathName = FfsFile.GenFfs(IsMakefile=Flag)
                if FfsFile.OverrideAttribs is not None:
                    FileName = os.path.basename(FilePathName)
                    TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
                    if not os.path.exists(TmpOutputDir) :
                        os.makedirs(TmpOutputDir)
                    TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
                    
                    GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, 
                                                           [FilePathName], 
                                                           [], 
                                                           FfsFile.OverrideAttribs.NeedCompress, 
                                                           FfsFile.OverrideAttribs.PciClassCode, 
                                                           FfsFile.OverrideAttribs.PciRevision, 
                                                           FfsFile.OverrideAttribs.PciDeviceId, 
                                                           FfsFile.OverrideAttribs.PciVendorId,
                                                           IsMakefile=Flag)
                    BinFileList.append(TmpOutputFile)
                else:
                    if FfsFile.FileType == 'EFI':
                        EfiFileList.append(FilePathName)
                    else:
                        BinFileList.append(FilePathName)
                        
        #
        # Call EfiRom tool
        #
        OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName)
        OutputFile = OutputFile + '.rom'
        
        GenFdsGlobalVariable.GenerateOptionRom(
                                OutputFile,
                                EfiFileList,
                                BinFileList,
                                IsMakefile=Flag)

        if not Flag:
            GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
        GenFdsGlobalVariable.SharpCounter = 0
        
        return OutputFile

class OverrideAttribs:
        
    ## The constructor
    #
    #   @param  self        The object pointer
    #
    def __init__(self):
        
        self.PciVendorId = None
        self.PciClassCode = None
        self.PciDeviceId = None
        self.PciRevision = None
        self.NeedCompress = None
