## @file
# process FV image section generation
#
#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import absolute_import
from . import Section
from io import BytesIO
from .Ffs import SectionSuffix
import subprocess
from .GenFdsGlobalVariable import GenFdsGlobalVariable
import Common.LongFilePathOs as os
from CommonDataClass.FdfClass import FvImageSectionClassObject
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common import EdkLogger
from Common.BuildToolError import *
from Common.DataType import *

## generate FV image section
#
#
class FvImageSection(FvImageSectionClassObject):

    ## The constructor
    #
    #   @param  self        The object pointer
    #
    def __init__(self):
        FvImageSectionClassObject.__init__(self)

    ## GenSection() method
    #
    #   Generate FV image section
    #
    #   @param  self        The object pointer
    #   @param  OutputPath  Where to place output file
    #   @param  ModuleName  Which module this section belongs to
    #   @param  SecNum      Index of section
    #   @param  KeyStringList  Filter for inputs of section generation
    #   @param  FfsInf      FfsInfStatement object that contains this section data
    #   @param  Dict        dictionary contains macro and its value
    #   @retval tuple       (Generated file name, section alignment)
    #
    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False):

        OutputFileList = []
        if Dict is None:
            Dict = {}
        if self.FvFileType is not None:
            FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
            if IsSect :
                return FileList, self.Alignment

            Num = SecNum

            MaxFvAlignment = 0
            for FvFileName in FileList:
                FvAlignmentValue = 0
                if os.path.isfile(FvFileName):
                    FvFileObj = open (FvFileName, 'rb')
                    FvFileObj.seek(0)
                    # PI FvHeader is 0x48 byte
                    FvHeaderBuffer = FvFileObj.read(0x48)
                    # FV alignment position.
                    if isinstance(FvHeaderBuffer[0x2E], str):
                        FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
                    else:
                        FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F)
                    FvFileObj.close()
                if FvAlignmentValue > MaxFvAlignment:
                    MaxFvAlignment = FvAlignmentValue

                OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get("FV_IMAGE"))
                GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
                OutputFileList.append(OutputFile)

            # MaxFvAlignment is larger than or equal to 1K
            if MaxFvAlignment >= 0x400:
                if MaxFvAlignment >= 0x100000:
                    #The max alignment supported by FFS is 16M.
                    if MaxFvAlignment >= 0x1000000:
                        self.Alignment = "16M"
                    else:
                        self.Alignment = str(MaxFvAlignment // 0x100000) + "M"
                else:
                    self.Alignment = str (MaxFvAlignment // 0x400) + "K"
            else:
                # MaxFvAlignment is less than 1K
                self.Alignment = str (MaxFvAlignment)

            return OutputFileList, self.Alignment
        #
        # Generate Fv
        #
        if self.FvName is not None:
            Buffer = BytesIO()
            Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
            if Fv is not None:
                self.Fv = Fv
                if not self.FvAddr and self.Fv.BaseAddress:
                    self.FvAddr = self.Fv.BaseAddress
                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile)
                if Fv.FvAlignment is not None:
                    if self.Alignment is None:
                        self.Alignment = Fv.FvAlignment
                    else:
                        if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
                            self.Alignment = Fv.FvAlignment
            else:
                if self.FvFileName is not None:
                    FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName)
                    if os.path.isfile(FvFileName):
                        FvFileObj = open (FvFileName, 'rb')
                        FvFileObj.seek(0)
                        # PI FvHeader is 0x48 byte
                        FvHeaderBuffer = FvFileObj.read(0x48)
                        # FV alignment position.
                        if isinstance(FvHeaderBuffer[0x2E], str):
                            FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
                        else:
                            FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F)
                        # FvAlignmentValue is larger than or equal to 1K
                        if FvAlignmentValue >= 0x400:
                            if FvAlignmentValue >= 0x100000:
                                #The max alignment supported by FFS is 16M.
                                if FvAlignmentValue >= 0x1000000:
                                    self.Alignment = "16M"
                                else:
                                    self.Alignment = str(FvAlignmentValue // 0x100000) + "M"
                            else:
                                self.Alignment = str (FvAlignmentValue // 0x400) + "K"
                        else:
                            # FvAlignmentValue is less than 1K
                            self.Alignment = str (FvAlignmentValue)
                        FvFileObj.close()
                    else:
                        if len (mws.getPkgPath()) == 0:
                            EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in WORKSPACE: %s" % self.FvFileName, GenFdsGlobalVariable.WorkSpaceDir)
                        else:
                            EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.FvFileName, '\n\t'.join(mws.getPkgPath())))

                else:
                    EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName)

            #
            # Prepare the parameter of GenSection
            #
            OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("FV_IMAGE"))
            GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
            OutputFileList.append(OutputFile)

            return OutputFileList, self.Alignment
