#!/usr/bin/env python3
# Copyright (c) 2009 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.

import optparse # pylint: disable=deprecated-module
import sys

import ExtensionMgrLib
from ExtensionMgrLib import errors
import PyClient
import Tracing

__defaultTraceHandle__ = Tracing.Handle( "InstallExtension" )
t0 = Tracing.trace0


usage = """
InstallExtension [-s <sysname>] [-q] <extension-name>

Installs the extension specified by <extension-name>.  The extension must
already be present in the extensions filesystem.
"""

def main():
   parser = optparse.OptionParser( usage=usage )
   parser.add_option( "-s", "--sysname", action="store", default="ar",
      help="system name (default: %default)" )
   parser.add_option( "-f", "--force", action="store_true", default=False,
      help="ignore conflicts and dependencies (default: %default)" )
   parser.add_option( "-q", "--quiet", action="store_true", default=False,
      help="suppress output (default: %default)" )
   parser.add_option( "-i", "--signatureIgnored", action="store_true",
                      default=False,
      help="ignore signature checking for this extension if checking is enabled" )
   parser.add_option( "-o", "--output", action="store",
                      default=ExtensionMgrLib.DEFAULT_STATUS_FILE,
                      help="save extension status to file (default %default)" )
   options, args = parser.parse_args()
   if len( args ) != 1:
      parser.error( "No extension name specified" )

   def out( *a, **kw ):
      if not options.quiet:
         sys.stderr.write( *a, **kw )

   extensionName = args[0]
   pc = PyClient.PyClient( options.sysname, "Sysdb" )
   root = pc.agentRoot()
   status = root.entity[ ExtensionMgrLib.statusPath() ]
   info = ExtensionMgrLib.latestExtensionForName( extensionName, status )
   if info is None:
      # pylint: disable-next=consider-using-f-string
      out( "Extension %s is not present\n" % extensionName )
      return 1
   try:
      oldInfo = ExtensionMgrLib.checkIfUpgrading( status, info )
      ExtensionMgrLib.installExtension( status, info, force=options.force )
      config = root.entity[ ExtensionMgrLib.configPath() ]
      if oldInfo is not None:
         # package has been upgraded 
         oldInfo.status = 'notInstalled'
         oldInfo.installedPackage.clear()
         ExtensionMgrLib.removeFromConfig( config, oldInfo.filename )
         ExtensionMgrLib.updateStatus( status, oldInfo.primaryPkg, install=False )
      ExtensionMgrLib.addToConfig( config, info.filename, info.format,
                                   options.force, options.signatureIgnored )
      ExtensionMgrLib.updateStatus( status, info.primaryPkg, install=True )
      # save extension to file so Sysdb restart can reload the status
      ExtensionMgrLib.saveInstalledExtensionStatus( root, options.output )
      return 0
   except errors.InstallError as e:
      out( f"Error installing {extensionName}: {e}\n" )
      return 1


if __name__ == '__main__':
   sys.exit( main() )
