"""
_MonitorState_

Monitoring Metrics generated by Updator functions are stored
in a MonitorState object derived from the UpdateDict class.

This object is then passed to the Monitors during the periodic update
cycle, so that the monitor plugins can access/manipulate the information
in the MonitorState

"""

__version__ = "$Revision: 1.1 $"
__revision__ = "$Id: MonitorState.py,v 1.1 2006/04/10 17:38:42 evansde Exp $"
__author__ = "evansde@fnal.gov"

import os
import socket

from ShREEK.UpdateDict import UpdateDict

_StaticFields = {
    'JobDirectory' : os.getcwd(), 
    'Hostname' : socket.gethostbyaddr(socket.gethostname())[0], 
    'HostIP' : socket.gethostbyname(socket.gethostname()), 
    }


class MonitorState(UpdateDict):
    """
    _MonitorState_
    
    Dictionary based State monitoring class.
    Each key can have a plugin Updator method associated
    with it that is called on the periodic update cycle
    to set that particular field.

    
    """
    def __init__(self):
        UpdateDict.__init__(self)
        #  //
        # // Set static value fields for job
        #//  Dynamic fields are created by the Updator plugins
        self.update(_StaticFields)
        self.ignoreErrors = False
        

    def loadExtenFields(self, extenDynamicFields = None):
        """
        _loadExtenFields_

        
        Load set of extension dynamic fields.
        """
        if extenDynamicFields == None:
            return
        #  //
        # // load set of extension dynamic fields, hand off
        #//  exceptions to Executor
        for key, val in extenDynamicFields.items():
            self.addUpdateKey(key, "NotUpdated", val)
        return

    #  //
    # // Wrap UpdateDict Update method to catch exceptions and pass them
    #//  back to the Executor to be handled
    def updateState(self):
        """
        Wrap UpdateDict doUpdate method to catch exceptions and pass them
        back to the Executor to be handled.
        """
        try:
            UpdateDict.doUpdate(self)
        except StandardError, ex:
            if self.ignoreErrors:
                msg = "WARNING: Error ignored when updating MonitorState:\n"
                msg += str(ex)
                print "WARNING:", msg
            else:
                raise ex
            
        
    #  //
    # // String Rep for nice printouts
    #//
    def __str__(self):
        """
        Convert instance to string format.
        """
        result = '***MonitorState Printout***\n'
        for key, val in self.items():
            result += '%s : \011%s' % (key, val)
            if self._Updators.has_key(key):
                result += ' :\011%s\n' % self._Updators[key].func_name
            else:
                result += ' :\011 Static key\n'
        result +='***End Monitor State***\n'
        return result
        

