## @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="store", 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:
            if not Opt.PackFileToInstall.endswith('.dist'):
                Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)

            AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)
            if not AbsPath:
                Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)

            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)
