## @file
#
# This file is the main entry for UPT 
#
# Copyright (c) 2011 - 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.
#

'''
UPT
'''

## import modules
#
import locale
import sys
encoding = locale.getdefaultlocale()[1]
if encoding:
    reload(sys)
    sys.setdefaultencoding(encoding)
from Core import FileHook
import os.path
from sys import platform
import platform as pf
from optparse import OptionParser
from traceback import format_exc
from platform import python_version

from Logger import StringTable as ST
import Logger.Log as Logger
from Logger.StringTable import MSG_VERSION
from Logger.StringTable import MSG_DESCRIPTION
from Logger.StringTable import MSG_USAGE
from Logger.ToolError import FILE_NOT_FOUND
from Logger.ToolError import OPTION_MISSING
from Logger.ToolError import FILE_TYPE_MISMATCH
from Logger.ToolError import OPTION_CONFLICT
from Logger.ToolError import FatalError
from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR
from Common.MultipleWorkspace import MultipleWorkspace as mws

import MkPkg
import InstallPkg
import RmPkg
import InventoryWs
import ReplacePkg
import TestInstall
from Library.Misc import GetWorkspace
from Library import GlobalData
from Core.IpiDb import IpiDatabase
from BuildVersion import gBUILD_VERSION

## CheckConflictOption
#
# CheckConflictOption
#
def CheckConflictOption(Opt):
    if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \
    and Opt.InventoryWs:
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE)
    elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove):
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE)
    elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove):
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION)
    elif Opt.PackFileToCreate and Opt.PackFileToInstall:
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE)
    elif Opt.PackFileToInstall and Opt.PackFileToRemove:
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE)
    elif Opt.PackFileToCreate and  Opt.PackFileToRemove:
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
    elif Opt.TestDistFiles and (Opt.PackFileToCreate or Opt.PackFileToInstall \
                                or Opt.PackFileToRemove or Opt.PackFileToReplace):
        Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)

    if Opt.CustomPath and Opt.UseGuidedPkgPath:
        Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH)
        Opt.UseGuidedPkgPath = False

## SetLogLevel
#
def SetLogLevel(Opt):
    if Opt.opt_verbose:
        Logger.SetLevel(Logger.VERBOSE)
    elif Opt.opt_quiet:
        Logger.SetLevel(Logger.QUIET + 1)
    elif Opt.debug_level != None:
        if Opt.debug_level < 0 or Opt.debug_level > 9:
            Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL)
            Logger.SetLevel(Logger.INFO)
        else:
            Logger.SetLevel(Opt.debug_level + 1)
    elif Opt.opt_slient:
        Logger.SetLevel(Logger.SILENT)
    else:
        Logger.SetLevel(Logger.INFO)

## Main
#
# Main
#
def Main():
    Logger.Initialize()

    Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION,
                          prog="UPT.exe", usage=MSG_USAGE)

    Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO)

    Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose",
                      help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT)

    Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY)

    Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY)

    Parser.add_option("-i", "--install", action="append", type="string", dest="Install_Distribution_Package_File",
                      help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL)

    Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File",
                      help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE)

    Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File",
                      help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE)

    Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File",
                      help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE)

    Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename",
                      help=ST.HLP_SPECIFY_DEC_NAME_CREATE)

    Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename",
                      help=ST.HLP_SPECIFY_INF_NAME_CREATE)

    Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed",
                      help=ST.HLP_LIST_DIST_INSTALLED)

    Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT)

    Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT)

    Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK)

    Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File",
                      help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE)

    Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File",
                      help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED)

    Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS)

    Parser.add_option("-j", "--test-install", action="append", type="string",
                      dest="Test_Install_Distribution_Package_Files", help=ST.HLP_TEST_INSTALL)

    Opt = Parser.parse_args()[0]

    Var2Var = [
        ("PackageInformationDataFile", Opt.Package_Information_Data_File),
        ("PackFileToInstall", Opt.Install_Distribution_Package_File),
        ("PackFileToCreate", Opt.Create_Distribution_Package_File),
        ("PackFileToRemove", Opt.Remove_Distribution_Package_File),
        ("PackageFileList", Opt.EDK2_DEC_Filename),
        ("ModuleFileList", Opt.EDK2_INF_Filename),
        ("InventoryWs", Opt.List_Dist_Installed),
        ("PackFileToReplace", Opt.Replace_Distribution_Package_File),
        ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File),
        ("UseGuidedPkgPath", Opt.Use_Guided_Paths),
        ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files)
    ]

    for Var in Var2Var:
        setattr(Opt, Var[0], Var[1])

    try:
        GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace()
    except FatalError, XExcept:
        if Logger.GetLevel() <= Logger.DEBUG_9:
            Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())
        return XExcept.args[0]

    # Support WORKSPACE is a long path
    # Only works for windows system
    if pf.system() == 'Windows':
        Vol = 'B:'
        for Index in range(90, 65, -1):
            Vol = chr(Index) + ':'
            if not os.path.isdir(Vol):
                os.system('subst %s "%s"' % (Vol, GlobalData.gWORKSPACE))
                break
        GlobalData.gWORKSPACE = '%s\\' % Vol

    WorkspaceDir = GlobalData.gWORKSPACE

    SetLogLevel(Opt)

    Mgr = FileHook.RecoverMgr(WorkspaceDir)
    FileHook.SetRecoverMgr(Mgr)

    GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \
                                                               "Conf/DistributionPackageDatabase.db")), WorkspaceDir)
    GlobalData.gDB.InitDatabase(Opt.SkipLock)

    #
    # Make sure the Db will get closed correctly
    #
    try:
        ReturnCode = 0
        CheckConflictOption(Opt)

        RunModule = None
        if Opt.PackFileToCreate:
            if Opt.PackageInformationDataFile:
                if not os.path.exists(Opt.PackageInformationDataFile):
                    if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)):
                        Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile)
                    else:
                        Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)
            else:
                Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION)
            if not Opt.PackFileToCreate.endswith('.dist'):
                Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate)
            RunModule = MkPkg.Main

        elif Opt.PackFileToInstall:
            AbsPath = []
            for Item in Opt.PackFileToInstall:
                if not Item.endswith('.dist'):
                    Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Item)

                AbsPath.append(GetFullPathDist(Item, WorkspaceDir))
                if not AbsPath:
                    Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Item)

            Opt.PackFileToInstall = AbsPath
            setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
            RunModule = InstallPkg.Main

        elif Opt.PackFileToRemove:
            if not Opt.PackFileToRemove.endswith('.dist'):
                Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove)
            head, tail = os.path.split(Opt.PackFileToRemove)
            if head or not tail:
                Logger.Error("RemovePkg",
                             FILE_TYPE_MISMATCH,
                             ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)

            setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)
            RunModule = RmPkg.Main
        elif Opt.InventoryWs:
            RunModule = InventoryWs.Main

        elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace:
            Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION)

        elif Opt.PackFileToReplace:
            if not Opt.PackFileToReplace.endswith('.dist'):
                Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace)
            if not Opt.PackFileToBeReplaced:
                Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION)
            if not Opt.PackFileToBeReplaced.endswith('.dist'):
                Logger.Error("ReplacePkg",
                             FILE_TYPE_MISMATCH,
                             ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced)

            head, tail = os.path.split(Opt.PackFileToBeReplaced)
            if head or not tail:
                Logger.Error("ReplacePkg",
                             FILE_TYPE_MISMATCH,
                             ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced)

            AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir)
            if not AbsPath:
                Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace)

            Opt.PackFileToReplace = AbsPath
            RunModule = ReplacePkg.Main

        elif Opt.Test_Install_Distribution_Package_Files:
            for Dist in Opt.Test_Install_Distribution_Package_Files:
                if not Dist.endswith('.dist'):
                    Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist)

            setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files)
            RunModule = TestInstall.Main

        else:
            Parser.print_usage()
            return OPTION_MISSING

        ReturnCode = RunModule(Opt)
    except FatalError, XExcept:
        ReturnCode = XExcept.args[0]
        if Logger.GetLevel() <= Logger.DEBUG_9:
            Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
                         format_exc())
    finally:
        try:
            if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:
                Logger.Quiet(ST.MSG_RECOVER_START)
                GlobalData.gDB.RollBack()
                Mgr.rollback()
                Logger.Quiet(ST.MSG_RECOVER_DONE)
            else:
                GlobalData.gDB.Commit()
                Mgr.commit()
        except StandardError:
            Logger.Quiet(ST.MSG_RECOVER_FAIL)
        GlobalData.gDB.CloseDb()

        if pf.system() == 'Windows':
            os.system('subst %s /D' % GlobalData.gWORKSPACE.replace('\\',''))

    return ReturnCode

## GetFullPathDist
#
#  This function will check DistFile existence, if not absolute path, then try current working directory,
#  then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
#
# @param DistFile:       The distribution file in either relative path or absolute path
# @param WorkspaceDir:   Workspace Directory
# @return AbsPath:       The Absolute path of the distribution file if existed, None else
#
def GetFullPathDist(DistFile, WorkspaceDir):
    if os.path.isabs(DistFile):
        if not (os.path.exists(DistFile) and os.path.isfile(DistFile)):
            return None
        else:
            return DistFile
    else:
        AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile))
        if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
            AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile))
            if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
                return None

        return AbsPath

if __name__ == '__main__':
    RETVAL = Main()
    #
    # 0-127 is a safe return range, and 1 is a standard default error
    #
    if RETVAL < 0 or RETVAL > 127:
        RETVAL = 1
    sys.exit(RETVAL)
