# Copyright 2019, 2021 VMware, Inc.
# All rights reserved. -- VMware Confidential

"""ESXi Advanced Config Options.

"""
import subprocess

from esxutils import EsxcliError, runCli

ESXCLI_USER = ['system', 'settings', 'advanced']
ESXCLI_VMK  = ['system', 'settings', 'kernel']

def addStrUserVar(name, desc, default, hidden=False):
   """Register a new Advanced Config Option in the /UserVars tree.
   """
   cmd = ['add', '-o', name, '-t', 'string', '-d', desc, '-s', default]
   if hidden:
      cmd += ['--hidden']

   try:
      runCli(ESXCLI_USER + cmd)
   except EsxcliError:
      raise OSError("/UserVars/%s: failed to add string AdvancedOption" % name)

def deleteUserVar(name):
   """Register a new Advanced Config Option in the /UserVars tree.
   """
   cmd = ['remove', '-o', name]

   try:
      runCli(ESXCLI_USER + cmd)
   except EsxcliError:
      raise OSError("/UserVars/%s: failed to delete Advanced Option" % name)

def getUserVar(name, *args):
   """Get a UserVars Advanced Option. The optional args parameter returns the
      user specified default value if the key is not found, otherwise
      a KeyError exception will be raised if nothing is passed in.
   """
   cmd = ['list', '-o', '/UserVars/%s' % name]

   try:
      opt = runCli(ESXCLI_USER + cmd, evalOutput=True)[0]
   except EsxcliError:
      if len(args) > 0:
         return args[0]
      else:
         raise KeyError("%s: Advanced User Option is not defined" % name)

   return opt['Int Value' ] if opt['Type'] == 'integer' else opt['String Value']

def setUserVar(name, value):
   """Set a UserVars Advanced Option.
   """
   cmd = ['set', '-o', "/UserVars/%s" % name,
          '-i' if isinstance(value, int) else '-s', str(value)]

   runCli(ESXCLI_USER + cmd)

def getVmkCfgOpt(name, default=False):
   """Get a VMKernel Config Option.
   """
   cmd = ['list', '-o', name]

   opt = runCli(ESXCLI_VMK + cmd, evalOutput=True)[0]
   if default:
      value = opt['Default']
   else:
      value = opt['Runtime']

   if opt['Type'].startswith(('int', 'uint')):
      return int(value)
   elif opt['Type'] == 'Bool':
      return value.lower() == 'true'
   else:
      return value
