## @file
# This is the base class for applications that operate on an EDK II Workspace 
#
# 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 os, sys, time
from DataType import *

## EdkIIWorkspace
#
# Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.
# 
# @var StartTime:       Time of build system starting
# @var PrintRunTime:    Printable time of build system running
# @var PrintRunStatus:  Printable status of build system running
# @var RunStatus:       Status of build system running
#
class EdkIIWorkspace:
    def __init__(self):
        self.StartTime = time.time()
        self.PrintRunTime = False
        self.PrintRunStatus = False
        self.RunStatus = ''
        
        #
        # Check environment valiable 'WORKSPACE'
        #
        if os.environ.get('WORKSPACE') == None:
            print 'ERROR: WORKSPACE not defined.    Please run EdkSetup from the EDK II install directory.'
            return False

        self.CurrentWorkingDir = os.getcwd()
        
        self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE'))
        (Drive, Path) = os.path.splitdrive(self.WorkspaceDir)
        if Drive == '':
            (Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir)
            if Drive != '':
                self.WorkspaceDir = Drive + Path
        else:
            self.WorkspaceDir = Drive.upper() + Path

        self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir)
            
        try:
            #
            # Load TianoCoreOrgLogo, used for GUI tool
            #
            self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF)
        except:
            self.Icon = None
            
        self.Verbose = False
        for Arg in sys.argv:
            if Arg.lower() == '-v':
                self.Verbose = True
    
    ## Close build system
    #
    # Close build system and print running time and status
    #
    def Close(self):
        if self.PrintRunTime:
            Seconds = int(time.time() - self.StartTime)
            if Seconds < 60:
                print 'Run Time: %d seconds' % (Seconds)
            else:
                Minutes = Seconds / 60
                Seconds = Seconds % 60
                if Minutes < 60:
                    print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds)
                else:
                    Hours = Minutes / 60
                    Minutes = Minutes % 60
                    print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds)
        if self.RunStatus != '':
            print self.RunStatus

    ## Convert to a workspace relative filename
    #
    # Convert a full path filename to a workspace relative filename.
    #
    # @param FileName:  The filename to be Converted
    #
    # @retval None    Workspace dir is not found in the full path
    # @retval string  The relative filename
    #
    def WorkspaceRelativePath(self, FileName):
        FileName = os.path.realpath(FileName)
        if FileName.find(self.WorkspaceDir) != 0:
            return None
        return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/')

    ## Convert to a full path filename
    #
    # Convert a workspace relative filename to a full path filename.
    #
    # @param FileName:  The filename to be Converted
    #
    # @retval string  The full path filename
    #
    def WorkspaceFile(self, FileName):
        return os.path.realpath(os.path.join(self.WorkspaceDir,FileName))

    ## Convert to a real path filename
    #
    # Convert ${WORKSPACE} to real path
    #
    # @param FileName:  The filename to be Converted
    #
    # @retval string  The full path filename
    #
    def WorkspacePathConvert(self, FileName):
        return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir))

    ## Convert XML into a DOM
    #
    # Parse an XML file into a DOM and return the DOM.
    #
    # @param FileName:  The filename to be parsed
    #
    # @retval XmlParseFile (self.WorkspaceFile(FileName))
    #
    def XmlParseFile (self, FileName):
        if self.Verbose:
            print FileName
        return XmlParseFile (self.WorkspaceFile(FileName))

    ## Convert a XML section
    #
    # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.
    #
    # @param FileName:    The filename to be parsed
    # @param SectionTag:  The tag name of the section to be parsed
    #
    # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)
    #
    def XmlParseFileSection (self, FileName, SectionTag):
        if self.Verbose:
            print FileName
        return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag)        

    ## Save a XML file
    #
    # Save a DOM(Document Object Model) into an XML file.
    #
    # @param Dom:       The Dom to be saved
    # @param FileName:  The filename
    #
    # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName))
    #
    def XmlSaveFile (self, Dom, FileName):
        if self.Verbose:
            print FileName
        return XmlSaveFile (Dom, self.WorkspaceFile(FileName))

    ## Convert Text File To Dictionary
    #
    # Convert a workspace relative text file to a dictionary of (name:value) pairs.
    #
    # @param FileName:             Text filename
    # @param Dictionary:           Dictionary to store data
    # @param CommentCharacter:     Comment char, be used to ignore comment content
    # @param KeySplitCharacter:    Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
    # @param ValueSplitFlag:       Value split flag, be used to decide if has multiple values
    # @param ValueSplitCharacter:  Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
    #
    # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
    #
    def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
        if self.Verbose:
            print FileName
        return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)

    ## Convert Dictionary To Text File
    #
    # Convert a dictionary of (name:value) pairs to a workspace relative text file.
    #
    # @param FileName:             Text filename
    # @param Dictionary:           Dictionary to store data
    # @param CommentCharacter:     Comment char, be used to ignore comment content
    # @param KeySplitCharacter:    Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
    # @param ValueSplitFlag:       Value split flag, be used to decide if has multiple values
    # @param ValueSplitCharacter:  Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
    #
    # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)
    #
    def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
        if self.Verbose:
            print FileName
        return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter)

## Convert Text File To Dictionary
#
# Convert a text file to a dictionary of (name:value) pairs.
#
# @param FileName:             Text filename
# @param Dictionary:           Dictionary to store data
# @param CommentCharacter:     Comment char, be used to ignore comment content
# @param KeySplitCharacter:    Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag:       Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter:  Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval True  Convert successfully
# @retval False Open file failed
#
def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
    try:
        F = open(FileName,'r')
    except:
        return False
    Keys = []
    for Line in F:
        LineList = Line.split(KeySplitCharacter,1)
        if len(LineList) >= 2:
            Key = LineList[0].split()
            if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: 
                if ValueSplitFlag:
                    Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter)
                else:
                    Dictionary[Key[0]] = LineList[1].strip().replace('\\','/')
                Keys += [Key[0]]
    F.close()
    return True

## Convert Dictionary To Text File
#
# Convert a dictionary of (name:value) pairs to a text file.
#
# @param FileName:             Text filename
# @param Dictionary:           Dictionary to store data
# @param CommentCharacter:     Comment char, be used to ignore comment content
# @param KeySplitCharacter:    Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
# @param ValueSplitFlag:       Value split flag, be used to decide if has multiple values
# @param ValueSplitCharacter:  Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
#
# @retval True  Convert successfully
# @retval False Open file failed
#
def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter):
    try:
        F = open(FileName,'r')
        Lines = []
        Lines = F.readlines()
        F.close()
    except:
        Lines = []
    Keys = Dictionary.keys()
    MaxLength = 0
    for Key in Keys:
        if len(Key) > MaxLength:
            MaxLength = len(Key)
    Index = 0
    for Line in Lines:
        LineList = Line.split(KeySplitCharacter,1)
        if len(LineList) >= 2:
            Key = LineList[0].split()
            if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary:
                if ValueSplitFlag:
                    Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]]))
                else:
                    Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]])
                Lines.pop(Index)
                if Key[0] in Keys:
                    Lines.insert(Index,Line)
                    Keys.remove(Key[0])
        Index += 1
    for RemainingKey in Keys:
        if ValueSplitFlag:
            Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey])) 
        else:
            Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey])
        Lines.append(Line)
    try:
        F = open(FileName,'w')
    except:
        return False
    F.writelines(Lines)
    F.close()
    return True

## Create a new directory
#
# @param Directory:           Directory to be created
#
def CreateDirectory(Directory):
    if not os.access(Directory, os.F_OK):
        os.makedirs (Directory)

## Create a new file
#
# @param Directory:  Directory to be created
# @param FileName:   Filename to be created
# @param Mode:       The mode of open file, defautl is 'w'
#
def CreateFile(Directory, FileName, Mode='w'):
    CreateDirectory (Directory)
    return open(os.path.join(Directory, FileName), Mode)

##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
    # Nothing to do here. Could do some unit tests
    pass