# Copyright 2014 VMware, Inc.  All rights reserved. -- VMware Confidential
#
'''Component message reporter.
'''

import logging

from .componentStatus import MessageInfo, ErrorInfo
from .execution_settings import getCoreExecutionSettings
from .defaultStatusFunctor import createSimpleComponentMessageUpdater

class MessageReporter(object):
   def __init__(self, setting = None, updateFun = None, statusFile = None):
      '''Reporter constructor
      @param setting: the execution setting. If unset, global
      execution setting will be used
      @type setting: CoreExecutionSettings

      @param updateFun: customized functor to update status with
      messages posted by a component. If not specified, a default
      functor updates to a local file (specified via statusFile) a
      serialized ComponentsExecutionStatusInfo instance.
      @type updateFun: functor, the input is a MessageInfo instance.

      @param statusFile: Currently used to specify the path to status file
      when updateFun is unset. It is ignored if updateFun is set.
      @type statusFile: string
      '''
      if not setting:
         self._cName = getCoreExecutionSettings().componentName
      else:
         self._cName = setting.componentName
      assert(self._cName)

      if not updateFun:
         assert(statusFile)
         self._updateFun = createSimpleComponentMessageUpdater(statusFile,
                                                               self._cName)
      else:
         self._updateFun = updateFun

   def postInfo(self, message):
      '''Append an informational message.

      @param message: message text
      @type message: LocalizableMesage
      '''
      try:
         self._updateFun(MessageInfo(message), MessageInfo.Severity.INFO)
      except:
         logging.exception("Error in posting message")

   def postWarning(self, message, resolution=None, problemId=None):
      '''Append a warning message.

      @param message: message text
      @type message: LocalizableMesage

      @param resolution: localizable message briefing problem resolution
      @type: LocalizableMessage

      @param problemId: Unique problem identificator which is mapped to
         external VMWare KB article explaining the problem.
      @type problemId: string
      '''
      try:
         self._updateFun(MessageInfo(message, resolution=resolution,
                                     problemId=problemId),
                         MessageInfo.Severity.WARNING)
      except:
         logging.exception("Error in posting message")

   def _postError(self, message, resolution=None, problemId=None):
      '''Stashes an error message and update error status. Typically
      component should update error information via
      ProgressReporter.failure(errInfo). This method should only be
      used in circumstances where it cannot work with progressReporter.

      @param message: message text
      @type message: LocalizableMesage

      @param resolution: localizable message briefing problem resolution
      @type: LocalizableMessage

      @param problemId: Unique problem identificator which is mapped to
         external VMWare KB article explaining the problem.
      @type problemId: string
      '''
      try:
         self._updateFun(ErrorInfo([message], componentKey=self._cName,
                                   resolution=resolution, problemId=problemId),
                         MessageInfo.Severity.ERROR)
      except:
         logging.exception("Error in posting message")
