#!/usr/bin/env python

# Copyright (c) 2008-2011 VMware, Inc.  All rights reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

from __future__ import print_function
import os
import sys
import time
import subprocess
import socket
import json

socket.setdefaulttimeout(30)

sys.path.append("/opt/vmware/lib/python/site-packages/")
import pywbem

import gettext
__t = gettext.translation('vamicli', '/opt/vmware/lib/locale', fallback=True)
_ = __t.ugettext if sys.version_info[0] < 3 else __t.gettext


__cliName__   = 'vamicli'
__printdebug__= 0
__subsystem__ = 'subsystem'
__command__   = 'command'
__arguments__ = 'arguments'

__cimserverurl__ = 'https://localhost:5489'
__defaultnamespace__ = 'root/cimv2'
__cert_file__    = '/opt/vmware/etc/sfcb/client.pem'
__key_file__     = '/opt/vmware/etc/sfcb/file.pem'

__subsys_network__ = 'network'
__showproxy__      = '--showproxy'

__subsys_update__  = 'update'
__checkupdate__    = '--check'
__installupdate__  = '--install'
__setupdaterepo__  = '--repo'
__getprogress__  = '--progress'

__subsys_version__ = 'version'
__appliance__      = '--appliance'
__studio__         = '--studio'

__subsys_service__ = 'service'
__installservice__ = '--install'
__uninstallservice__ = '--uninstall'

__studio_default_version__ = '2.0.0.0'
__studio_version_file__ = '/opt/vmware/etc/studio_version'
__update_progress_file__ = '/opt/vmware/var/lib/vami/update/data/update_progress.json'

__exit_error__      = 1
__exit_cli_error__  = 2

__connect_error_message__ = _('Internal error.  Please make sure sfcbd is running.')
__license_error_message__ = _('You must accept the license to install this update.')


VAMIMANAGER = '/opt/vmware/bin/vamimanager'


class vamiError(Exception):
  _message = ""
  _code = 0
  def __init__(self, newCode=0, newMessage=""):
    self.code = newCode
    self.message = newMessage

  def __str__(self):
    return self.message

  def getCode(self):
    return self.code


def printHelp():
  # errorMessage='\nUsage: ' + sys.argv[0] + ' <system> [options]\n'
  errorMessage = _('\nUsage: ') + os.path.basename(sys.argv[0]) + _(' <system> [options]\n')
  errorMessage += _('<system> may be:\n')
  errorMessage += '  ' + __subsys_network__ + _('          Network Configuration\n')
  errorMessage += '  ' + __subsys_update__  + _('           Update Management\n')
  errorMessage += '  ' + __subsys_version__ + _('          Version Information\n')
  errorMessage += '  ' + __subsys_service__ + _('          Service Management\n')
  errorMessage += '\n'
  errorMessage += _('  Use ') + os.path.basename(sys.argv[0]) + _(' <system> to see a list of options.\n')
  raise vamiError(__exit_cli_error__, errorMessage)


def getCIMConnection (url, namespace):
    cred = {}
    cred ['cert_file'] = __cert_file__
    cred ['key_file'] = __key_file__
    cliconn = pywbem.WBEMConnection (url, None, namespace, cred)
    return cliconn



def checkForFailure (jobinst, state):
  if state > 7:
    if jobinst.has_key('ErrorDescription'): # Job failed
       #It already give a proper error in jobinst
      errorMessage = _('\nFailure: ') + jobinst ['ErrorDescription'] + '\n'
    else:
      errorMessage = _('\nFailure: Job failed.\n')
    return 1, errorMessage
  return 0, ''



def queryJob (cliconn, jobref, flag):
  state = 0
  status = 'Unknown'
  errorMessage = ''
  retryCounter = 0
  while (state < 7 and retryCounter < 30):
    try:
      if(retryCounter > 0):
        time.sleep (4)
      else:
        time.sleep (0.5)
      jobinst = cliconn.GetInstance (jobref.copy())
      if (jobinst.has_key ('JobState')):
        state = jobinst ['JobState']
        retval, errorMessage = checkForFailure (jobinst, state)
        if retval == 1:
          return 1, errorMessage

        sys.stdout.write ('.')
        sys.stdout.flush ()
      else:
        errorMessage = _('\nFailure: Invalid response. Operation failed, please try again.\n')
        break

    except pywbem.CIMError as err:
      if (flag == True):
         if(retryCounter == 0):
            print (_('Connection to sfcbd lost'))
         retryCounter=retryCounter + 1
         print (_('Attempting to reconnect:'),retryCounter)
  return 0,errorMessage



def handleReturnValue (cliconn, rettuple, flag):
  if (rettuple [0] == 4096):
    outvals = rettuple [1]
    jobref = outvals ['Job']
    retValue, errorMessage = queryJob (cliconn, jobref, flag)
    if (retValue == 1):
      return 1, errorMessage
  else:
    print (_('Check for updates returned with a value - '),)
    print (rettuple [0])
  return 0, errorMessage


def showAvailableUpdates ():
  cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
  inst = cliconn.EnumerateInstanceNames('VAMI_SoftwareInstallationService')
  esis = cliconn.EnumerateInstances ('VAMI_ElementSoftwareIdentity')
  print (_('\nAvailable Updates - '))
  foundSI = False
  for esi in esis:
    ess = esi ['ElementSoftwareStatus']
    if (ess == [8]):
      foundSI = True
      inst = cliconn.GetInstance (esi['Antecedent'])
      print ('   ' + inst ['VersionString'])
  if (foundSI == False):
    print (_('   No available updates found'))


def checkAvailableUpdates (opts=[]):
  if len(opts) > 1:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showUpdateHelp(opts)

  try:
    cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
    inst = cliconn.EnumerateInstanceNames('VAMI_SoftwareInstallationService')
    rettuple = cliconn.InvokeMethod('CheckAvailableUpdates', inst [0])
    print (_('\nChecking for available updates, this process can take a few minutes...'),)
    retValue, errorMessage = handleReturnValue (cliconn, rettuple, False)
  except:
    raise vamiError(__exit_error__, __connect_error_message__)

  if (retValue == 1):
    raise vamiError(__exit_error__, errorMessage)

  try:
    showAvailableUpdates ()
  except:
    raise vamiError(__exit_error__, __connect_error_message__)


# --repo --user --password
def setLocalRepository(opts=[]):
  user=''
  passwd=''
  if len(opts) < 2:
    print (_('\nFailure: repo is not specified.'))
    showUpdateHelp(opts)
  elif (len(opts) == 3 or len(opts) == 5 ):
    print (_('\nFailure: Please specify the value.'))
    showUpdateHelp(opts)
  elif len(opts) == 4:
    if opts[2] == '--user':
      if (opts[3]) :
        user = opts[3]
    else:
      print (_('\nFailure: invalid input "') +  opts[2] +   _('" without --user.'))
      showUpdateHelp(opts)
  elif len(opts) == 6:
    if (opts[2] == '--user' and opts[3] and opts[4] == '--password' and opts[5] ):
      #both user/passwd non-empty
      user = opts[3]
      passwd = opts[5]
    elif (opts[4] == '--user' and opts[5] and opts[2] == '--password' and opts[3] ):
      #both passwd/user non-empty
      user = opts[5]
      passwd = opts[3]
    elif (opts[4] == '--user' and not opts[5]  and opts[2] == '--password' and not opts[3] ):
      #both passwd/user empty
      pass
    elif (opts[2] == '--user' and not opts[3]  and opts[4] == '--password' and not opts[5] ):
      #both passwd/user empty
      pass
    elif (opts[2] == '--user' and opts[3]  and opts[4] == '--password' and not opts[5] ):
      #empty password
      user = opts[3]
    elif (opts[4] == '--user' and opts[5] and opts[2] == '--password' and not opts[3] ):
      #empty passwrod
      user = opts[5]
    else :
      print (_('\nFailure: Please specify the value of user or keep both empty.'))
      showUpdateHelp(opts)

  try:
    cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
    inst = cliconn.EnumerateInstanceNames('VAMI_SoftwareInstallationService')
    rettuple = cliconn.InvokeMethod('SetLocalRepositoryAddress', inst [0], RepositoryAddress=opts[1], Username=user, Password=passwd)
    print (_('\nSet local repository address...'))
  except:
    raise vamiError(__exit_error__, __connect_error_message__)

  if ( rettuple[0] == 0L ):
    print (_('Done.'))
  else:
    raise vamiError(__exit_error__, '\nFailure: failed to set. Please check vami.log')


def parseUpdateProgressJson(detail):
  PHASE_DOWNLOAD = 'Download'
  PHASE_INSTALL = 'Install'

  if os.path.isfile(__update_progress_file__) :
    #empty file
    if os.stat(__update_progress_file__).st_size == 0 :
      print('Failed to get progress, exception happened at writing file during upgrading')
      return 1
  else:
    print('No update instance is running.')
    return 0

  #update is in process
  with open(__update_progress_file__, 'r') as f:
    data = json.load(f)

  phase = data['Phase']
  pkgnum = data['pkgNum']
  downloadnum = data['DownloadNum']

  if phase == PHASE_INSTALL :
    output = str(pkgnum) + " packages have been downloaded.\n"
    output += "Installing..."
  elif phase == PHASE_DOWNLOAD :
    output = str(downloadnum) + "/" + str(pkgnum) + " packages downloaded.\n";
    output += "Downloading..."
    if detail :
      for rcd in data['pkgArray'] :
        output +=  "\n" + rcd['Name'] + "\t" + rcd['Status']

  print(output)
  return 0

def getUpdateProgress(opts=[]):
  detail=False
  if len(opts) > 1 :
    if (opts[1] == '--detail'):
      detail=True
    else:
      print (_('\nFailure: "') + opts[0] + _('" is not a supported argument.'))
      showUpdateHelp(opts)

  ret = parseUpdateProgressJson(detail)
  return ret


def installLatestUpdate (opts=[]):
  accepteula=False
  if len(opts) > 2:
    if (opts[2] == '--accepteula'):
      accepteula=True
    else:
      print (_('\nFailure: "') + opts[2] + _('" is not a supported argument.'))
      showUpdateHelp(opts)
  try:
    cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
    inst = cliconn.EnumerateInstanceNames('VAMI_SoftwareInstallationService')
    esis = cliconn.EnumerateInstances ('VAMI_ElementSoftwareIdentity')
  except:
    raise vamiError(__exit_error__, __connect_error_message__)

  foundSI = False
  for esi in esis:
    ess = esi ['ElementSoftwareStatus']
    if (ess == [8]):
      foundSI = True
      instance = cliconn.GetInstance (esi['Antecedent'])

      infoType = instance ['IdentityInfoType']
      infoValue = instance ['IdentityInfoValue']

      if ( accepteula == False ):
        for index, object in enumerate(infoType):
          if (object== u'VMware-VAMI:EULARequired' ):
            if (infoValue[index]==u'true'):
              rettuple = cliconn.InvokeMethod('GetEULA', instance.path)

              EULAs = rettuple[1]['EULA']

              if (len(EULAs) > 0):
                raw_input(_('Please agree to the following licenses to install the update.[enter]'))

                for EULA in EULAs:
                  while True:
                    os.popen('more',"w").write(EULA)
                    answer = raw_input(_("Do you agree?")+"[yes/no] ").lower()
                    if( answer == 'yes' ):
                      break
                    if( answer == 'no' ):
                      raise vamiError(__exit_error__, __license_error_message__)
                    else:
                      continue

      print (_('Installing version - '),)
      print (instance ['VersionString'])

      try:
        rettuple = cliconn.InvokeMethod('InstallFromSoftwareIdentity',
                                    inst [0], Source=esi['Antecedent'])
        retValue, errorMessage = handleReturnValue (cliconn, rettuple, True)
      except:
         raise vamiError(__exit_error__, __connect_error_message__)

      if (retValue == 1):
        raise vamiError(__exit_error__, errorMessage)

  if (foundSI == False):
    errorMessage = _('\nFailure: No updates to install\n')
    raise vamiError(__exit_error__, errorMessage)



def showVersion (opts=[]):
  if len(opts) > 1:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showVersionHelp(opts)
  try:
    cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
    esis = cliconn.EnumerateInstances ('VAMI_ElementSoftwareIdentity')
  except:
    raise vamiError(__exit_error__, __connect_error_message__)

  for esi in esis:
    ess = esi ['ElementSoftwareStatus']
    if (ess == [2, 6]):
      inst = cliconn.GetInstance (esi['Antecedent'])
      print ('Version - ' + inst ['VersionString'])
      print ('Description - ' + inst ['Description'])


def showStudioVersion (opts=[]):
  if len(opts) > 1:
    print (_('\nFailure: "') + opts[1] + _('" is not supported argument.'))
    showVersionHelp(opts)
  if os.path.exists(__studio_version_file__):
    fd = open(__studio_version_file__, "r")
    print ('Version - ' + fd.readline())
    fd.close()
  else:
    print ('Version - ' + __studio_default_version__)


def showProxy (opts=[]):
  if len(opts) > 1:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showNetworkHelp(opts)
  try:
    cliconn = getCIMConnection (__cimserverurl__, __defaultnamespace__)
    insts = cliconn.ExecQuery ('WQL', 'select ProxyServerAddress from VAMI_SoftwareInstallationService')
  except:
    raise vamiError(__exit_error__, __connect_error_message__)

  inst = insts [0]
  proxy = inst ['ProxyServerAddress']
  if len(proxy) > 0:
    print (proxy)
  else:
    print (_('No proxy configured'))


def installServiceTar (opts=[]):
    if len(opts) > 2:
        print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
        showServiceHelp(opts)
    cmd=[VAMIMANAGER]
    cmd.extend(opts)
    subprocess.call(cmd)

def uninstallServiceTar (opts=[]):
    if len(opts) > 2:
        print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
        showServiceHelp(opts)
    cmd=[VAMIMANAGER]
    cmd.extend(opts)
    subprocess.call(cmd)


def showLatestVersionHelp ():
  errorMessage = _('\nPlease specify <version>\n')
  errorMessage += _('Supported versions are:\n')
  errorMessage += _('  latest - install the latest version\n')
  raise vamiError(__exit_cli_error__, errorMessage)

def showInstallServiceHelp ():
  errorMessage = _('\nPlease specify <service_tar_file>\n')
  errorMessage += _('Where service_tar_file is the location of service tar file to install\n')
  raise vamiError(__exit_cli_error__, errorMessage)

def showUnInstallServiceHelp ():
  errorMessage = _('\nPlease specify <service_tar_file>\n')
  errorMessage += _('Where service_tar_file is the location of service tar file to uninstall\n')
  raise vamiError(__exit_cli_error__, errorMessage)


# FUNCTION NAME: installUpdate()
#
#   DESCRIPTION: Will handle arguments for the install update service.
#
#        INPUTS: The arguments list. opts[0] is the ID of the version to install.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def installUpdate (opts):
  if len(opts) == 1:
    showLatestVersionHelp()
  try:
    { 'latest'   : installLatestUpdate
    }[ opts[1] ](opts)
  except KeyError:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showLatestVersionHelp()

# FUNCTION NAME: installService()
#
#   DESCRIPTION: Will handle arguments for the install service.
#
#        INPUTS: The arguments list. opts[0] is the service tar file
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def installService (opts):
  if len(opts) == 1:
    showInstallServiceHelp()
  try:
    { __installservice__   : installServiceTar
    }[ opts[0] ](opts)
  except KeyError:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showInstallServiceHelp()

# FUNCTION NAME: uninstallService()
#
#   DESCRIPTION: Will handle arguments for the uninstall service.
#
#        INPUTS: The arguments list. opts[0] is the service tar file
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def uninstallService (opts):
  if len(opts) == 1:
    showUnInstallServiceHelp()
  try:
    {  __uninstallservice__   : uninstallServiceTar
    }[ opts[0] ](opts)
  except KeyError:
    print (_('\nFailure: "') + opts[1] + _('" is not a supported argument.'))
    showUnInstallServiceHelp()

# FUNCTION NAME: handleNetworkRequests()
#
#   DESCRIPTION: Will handle arguments for the network service.
#
#        INPUTS: The arguments list.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def handleNetworkRequests (opts):
  if len(opts) == 2:
    showNetworkHelp(opts)
  else:
    try:
      { __showproxy__ : showProxy
      }[ opts[2] ](opts[2:])
    except KeyError:
      print (_('\nFailure: "') + opts[2] + _('" is not a supported argument.'))
      showNetworkHelp(opts)



# FUNCTION NAME: showNetworkHelp()
#
#   DESCRIPTION: Show help for the network service.
#
#        INPUTS: The arguments list. opts[0] is the current command, opts[1] is the service argument
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def showNetworkHelp(opts):
  errorMessage = _('\nNetwork usage:\n')
  errorMessage += '  ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __showproxy__ + _('        -   Show the proxy setting\n')
  raise vamiError(__exit_cli_error__, errorMessage)



# FUNCTION NAME: handleUpdateRequests()
#
#   DESCRIPTION: Will handle arguments for the update service.
#
#        INPUTS: The arguments list.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def handleUpdateRequests (opts):
  if len(opts) == 2:
    showUpdateHelp(opts)
  else:
    try:
      { __checkupdate__   : checkAvailableUpdates,
        __installupdate__ : installUpdate,
        __setupdaterepo__: setLocalRepository,
        __getprogress__: getUpdateProgress
      }[ opts[2] ](opts[2:])
    except KeyError:
      print (_('\nFailure: "') + opts[2] + _('" is not a supported argument.'))
      showUpdateHelp(opts)


# FUNCTION NAME: showUpdateHelp()
#
#   DESCRIPTION: Show help for the update service.
#
#        INPUTS: The arguments list. opts[0] is the current command, opts[1] is the service argument
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def showUpdateHelp(opts):
  errorMessage = _('\nUpdate usage:\n')
  errorMessage += ' ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __checkupdate__ + _('                            - Check for new updates\n')
  errorMessage += ' ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __installupdate__ + _(' <version> [--accepteula] - Download and install update\n')
  errorMessage += ' ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __setupdaterepo__ + _(' <repositoryAddress> [--user <user> --password <password>] - Set repository address\n')
  errorMessage += ' ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __getprogress__ + _(' [--detail] - Check for update progress\n')
  raise vamiError(__exit_cli_error__, errorMessage)


# FUNCTION NAME: handleVersionRequests()
#
#   DESCRIPTION: Will handle arguments for the version service.
#
#        INPUTS: The arguments list.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def handleVersionRequests (opts):
  if len(opts) == 2:
    showVersionHelp(opts)
  else:
    try:
      { __appliance__ : showVersion,
        __studio__    : showStudioVersion
      }[ opts[2] ](opts[2:])
    except KeyError:
      print (_('\nFailure: "') + opts [2] + _('" is not a supported argument.'))
      showVersionHelp(opts)


# FUNCTION NAME: showVersionHelp()
#
#   DESCRIPTION: Show help for the version service.
#
#        INPUTS: The arguments list. opts[0] is the current command, opts[1] is the service argument
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def showVersionHelp(opts):
  errorMessage = _('\nVersion usage:\n')
  errorMessage += '  ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __appliance__ + _('        -   Show the version of this appliance\n')
  errorMessage += '  ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __studio__ + _('           -   Show the version of VMware Studio\n')
  raise vamiError(__exit_cli_error__, errorMessage)


# FUNCTION NAME: handleServiceRequests()
#
#   DESCRIPTION: Will handle arguments for Managing services.
#
#        INPUTS: The arguments list.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def handleServiceRequests (opts):
  if len(opts) == 2:
    showServiceHelp(opts)
  else:
    try:
      { __installservice__   : installService,
        __uninstallservice__ : uninstallService
      }[ opts[2] ](opts[2:])
    except KeyError:
      print (_('\nFailure: "') + opts[2] + _('" is not a supported argument.'))
      showServiceHelp(opts)


# FUNCTION NAME: showServiceHelp()
#
#   DESCRIPTION: Show help for Managing services.
#
#        INPUTS: The arguments list. opts[0] is the current command, opts[1] is the service argument
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def showServiceHelp(opts):
  errorMessage = _('\nService usage:\n')
  errorMessage += '  ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __installservice__ + _(' <service_tar_file>  -   Install given service tar file\n')
  errorMessage += '  ' + os.path.basename(opts[0]) + ' ' + opts[1] + ' ' + __uninstallservice__ + _(' <service_tar_file> -  UnInstall given service tar file\n')
  raise vamiError(__exit_cli_error__, errorMessage)


# FUNCTION NAME: main()
#
#   DESCRIPTION: The main function.  Will examin the arguments and if valid run
#                the correct sub-function.  Otherwise, it will print the usage.
#
#        INPUTS: The arguments list.
#
#       OUTPUTS: None.
#
#  RETURN VALUE: None.
#
#         NOTES: None.
#
#    REFERENCES: None.
#
def main():
  if len(sys.argv) == 1:
    printHelp()
  try:
    { __subsys_network__ : handleNetworkRequests,
      __subsys_update__  : handleUpdateRequests,
      __subsys_version__ : handleVersionRequests,
      __subsys_service__ : handleServiceRequests
    }[ sys.argv[1] ](sys.argv)
  except KeyError:
    print (_('\nFailure: "') + sys.argv[1] + _('" is not a valid system.'))
    printHelp()


if __name__ == '__main__':
  try:
    main()
  except vamiError as error:
    print (error)
    sys.exit(error.getCode())
  except:
    print (_('\nFailure: Unknown Error'))
    raise
    sys.exit(__exit_error__)


