#!/usr/bin/env python3
# Copyright (c) 2005-2006 Arastra, Inc.  All rights reserved.
# Arastra, Inc. Confidential and Proprietary.

# Restricted/Standalone CLI

# Set the 'NOPDB' environment variable before importing Tac to prevent us from
# ever dropping into PDB (see tacc/Tac/Excepthook.py), as doing so could permit a
# security violation.
import os
import sys

os.environ[ 'NOPDB' ] = '1'
# pylint: disable=wrong-import-position
import BasicCli
import BasicCliSession
import Cli
import CliArgParser
import EntityManager
import ExecCli

# Most command options don't apply
options = CliArgParser.parseArgs( privilege=True,
                                  configFile=False,
                                  disableGuards=False,
                                  echo=False,
                                  echoTimestamp=False,
                                  pdb=False,
                                  standalone=False,
                                  standaloneGuards=False,
                                  startupConfig=False,
                                  sysdbsockname=False,
                                  loadDynamicPlugins=True )

if options.load_dynamic_plugins:
   sys.argv.remove( '--load-dynamic-plugins' ) # ExecCli will call parseArgs again
   # Cause the loading of dynamic cli plugins right after the "always-on" ones
   os.environ[ "LOAD_DYNAMIC_PLUGIN" ] = "1"
   # And prevent barfing about dynamic plugins being loaded by default (which we only
   # do in workspaces, so A4_CHROOT does the trick).
   os.environ.pop( "A4_CHROOT", None )

cli = None
try:
   entityManager = EntityManager.Local( options.sysname )

   if options.load_dynamic_plugins:
      # Some dynamic cli plugins call mg.close(blocking=True), which will not work
      # at startup, so monkey patch it to False.
      def mgClose( self, callback=-1, blocking=False, msg="mounts to complete" ):
         return realMgClose( self, callback=callback, blocking=False, msg=msg )
      realMgClose = EntityManager.MountGroup.close
      EntityManager.MountGroup.close = mgClose

   def cliInitialized( cliInstance ):
      global cli
      cli = cliInstance

   Cli.initCli( entityManager, # pylint: disable=c-extension-no-member
                callback=cliInitialized,
                block=True,
                plugins=options.plugins,
                noPlugins=options.no_plugins,
                standalone=True )
   assert cli

   if 'AAA_AUTHN_ID' in os.environ:
      aaaAuthnId = int( os.environ.get( 'AAA_AUTHN_ID' ) )
   else:
      aaaAuthnId = None
   aaaUser = BasicCliSession.AaaUser( os.environ.get( 'AAA_AUTHN_USER' ),
                                      aaaAuthnId,
                                      os.getuid(), os.getgid() )
   session = BasicCliSession.Session( BasicCli.UnprivMode,
                                      entityManager,
                                      privLevel=options.privilege,
                                      disableAutoMore=options.disable_automore,
                                      disableAaa=options.disable_aaa,
                                      disableGuards=False,
                                      standalone=True,
                                      interactive=True,
                                      cli=cli,
                                      aaaUser=aaaUser )
   # setup Aaa
   aaaConfig = entityManager.root().entity[ 'cli/input/aaa' ]
   aaaConfig.aaaProvider = 'Aaa'

   if not options.command:
      # set up default prompt to make it more clear that we are in a standalone shell
      session.cliConfig.prompt = "Standalone%R%v%P"

      print( """
Note: Standalone CLI does not share data with other agents, but it can
run certain commands such as 'bash' to troubleshoot the system within
authentication and authorization constraints.
"""     )
   returnCode = ExecCli.execCli( entityManager=entityManager, session=session )
except KeyboardInterrupt:
   returnCode = 130

os._exit( returnCode ) # pylint: disable-msg=protected-access
