## @file
# process FD generation
#
#  Copyright (c) 2007, Intel Corporation
#
#  All rights reserved. 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 Region
import Fv
import os
import StringIO
import sys
from struct import *
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import FDClassObject
from Common import EdkLogger
from Common.BuildToolError import *
from Common.Misc import SaveFileOnChange

## generate FD
#
#
class FD(FDClassObject):
    ## The constructor
    #
    #   @param  self        The object pointer
    #
    def __init__(self):
        FDClassObject.__init__(self)

    ## GenFd() method
    #
    #   Generate FD
    #
    #   @param  self        The object pointer
    #   @param  FvBinDict   dictionary contains generated FV name and its file name
    #   @retval string      Generated FD file name
    #
    def GenFd (self, FvBinDict):
        #
        # Print Information
        #
        GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName)
        Offset = 0x00
        for item in self.BlockSizeList:
            Offset = Offset + item[0]  * item[1]
        if Offset != self.Size:
            EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
        GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
        for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
            GenFdsGlobalVariable.VerboseLogger(FvObj)

        GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################')
        self.GenVtfFile()

        FdBuffer = StringIO.StringIO('')
        PreviousRegionStart = -1
        PreviousRegionSize = 1
        for RegionObj in self.RegionList :
            if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
                EdkLogger.error("GenFds", GENFDS_ERROR,
                                'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\
                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
            elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
                EdkLogger.error("GenFds", GENFDS_ERROR,
                                'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
            elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
                GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
                PadRegion = Region.Region()
                PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                PadRegion.Size = RegionObj.Offset - PadRegion.Offset
                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
            PreviousRegionStart = RegionObj.Offset
            PreviousRegionSize = RegionObj.Size
            #
            # Call each region's AddToBuffer function
            #
            if PreviousRegionSize > self.Size:
                EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s size too small' % self.FdUiName)
            GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
        #
        # Create a empty Fd file
        #
        GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file')
        FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,
                                  self.FdUiName + '.fd')
        #FdFile = open(FdFileName, 'wb')

        #
        # Write the buffer contents to Fd file
        #
        GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
        SaveFileOnChange(FdFileName, FdBuffer.getvalue())
        #FdFile.write(FdBuffer.getvalue());
        #FdFile.close();
        FdBuffer.close();
        return FdFileName

    ## generate VTF
    #
    #   @param  self        The object pointer
    #
    def GenVtfFile (self) :
        #
        # Get this Fd's all Fv name
        #
        FvAddDict ={}
        FvList = []
        for RegionObj in self.RegionList:
            if RegionObj.RegionType == 'FV':
                if len(RegionObj.RegionDataList) == 1:
                    RegionData = RegionObj.RegionDataList[0]
                    FvList.append(RegionData.upper())
                    FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
                                                RegionObj.Offset, RegionObj.Size)
                else:
                    Offset = RegionObj.Offset
                    for RegionData in RegionObj.RegionDataList:
                        FvList.append(RegionData.upper())
                        FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
                        if len(FvObj.BlockSizeList) < 1:
                            EdkLogger.error("GenFds", GENFDS_ERROR,
                                            'FV.%s must point out FVs blocksize and Fv BlockNum' \
                                            % FvObj.UiFvName)
                        else:
                            Size = 0
                            for blockStatement in FvObj.BlockSizeList:
                                Size = Size + blockStatement[0] * blockStatement[1]
                            FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
                                                             Offset, Size)
                            Offset = Offset + Size
        #
        # Check whether this Fd need VTF
        #
        Flag = False
        for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList:
            compLocList = VtfObj.GetFvList()
            if set(compLocList).issubset(FvList):
                Flag = True
                break
        if Flag == True:
            self.vtfRawDict = VtfObj.GenVtf(FvAddDict)

    ## generate flash map file
    #
    #   @param  self        The object pointer
    #
    def GenFlashMap (self):
        pass








