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

from com.vmware.esx.settings_daemon_client import Notification
from com.vmware.vapi.std_client import LocalizableMessage
from datetime import datetime

from vmware.vapi.data.value import ListValue, StructValue
from vmware.vapi.data.definition import (ListDefinition, OptionalDefinition,
                                         StructDefinition)
from vmware.vapi.bindings.type import MapType, SetType

from .Constants import *

def createFormattedMessage(msg, args):
   """Format a message for VAPI.

      Copied from ../ImageManager/Scanner to remove dependency.
   """
   if args:
      # Messages in Constants are copied from VLCM on VC, they have positional
      # arguments that start from "{1}" rather than {0}. An extra argument will
      # save the effort of having two slightly different messages.
      return msg.format(*([''] + args))
   return msg

def createNotification(notificationId, msgId, msgArgs=None, resArgs=None,
                       type_=INFO):
   """ Create notification.

       Modified from ../ImageManager/Scanner to remove dependency.
   """
   notificationIdFull = DPU_PREFIX + notificationId
   msgIdFull = DPU_PREFIX + msgId

   defMsg = createFormattedMessage(NOTIFICATION_MSG[msgId], msgArgs)
   msg = LocalizableMessage(id=msgIdFull, default_message=defMsg,
                            args=msgArgs or [])
   resMsg = createFormattedMessage(RESOLUTION_MSG.get(notificationId, ''),
                                   resArgs)
   if resMsg:
      # Populate the optional resolution when there is actually a message.
      resId = msgIdFull + RESOLUTION_SUFFIX if resMsg else ''
      resolution = LocalizableMessage(id=resId,
                                      default_message=resMsg,
                                      args=resArgs or [])
   else:
      resolution = None
   return Notification(id=notificationIdFull,
                       time=datetime.utcnow(),
                       message=msg,
                       resolution=resolution,
                       type=type_)

def createDummyObjectForType(theType):
   """ Create a dummy object for the type:
          dummy are created for members
          empty are assigned to dict/list/set
          set release_date to datetime.min to avoid serialization issue
   """
   bType = theType().get_binding_type()
   kargs = {}
   for f in bType.get_field_names():
      if f == 'release_date':
         kargs[f] = datetime.min
         continue

      fieldType = bType.get_field(f)
      definition = bType.definition.get_field(f)

      if isinstance(definition, OptionalDefinition):
         # Use the element type for optional field.
         fieldType = fieldType.element_type
         definition = definition.element_type

      newValue = definition.new_value()
      if isinstance(newValue, StructValue):
         bindType = fieldType.resolved_type.binding_class
         value = createDummyObjectForType(bindType)
      elif isinstance(newValue, ListValue):
         if isinstance(fieldType, SetType):
            value = set()
         elif isinstance(fieldType, MapType):
            value = dict()
         else:
            value = list()
      else:
         value = newValue.value
      kargs[f] = value

   return theType(**kargs)
