#
#   File:    eventmgr-actions-d.prc
#   Author:  Margot Loren
#   Version: 1.20 01/04/12 12:47:49
#   Copyright (c) 1993-1998 Halcyon Inc.
#
#   Event Management Module Procedures for performing user actions, such
#   as "Delete Event", "Fix Event", and "Ack Event"
#

#############################################################################
#
# proc: shadowEventDelete
#
# Shadowmap operation to delete events.
# This routine gets invoked via an "snmp set" to shadowmap ?eventdelete.
#
# Usage: set failList [ shadowEventDelete inputData ]
#
# Input: inputData - list of three elements:
#                        <deleteList> - list of message ids to delete
#                        <operator>   - name of operator doing the delete
#                        <reason>     - reason for the delete (can be blank)
#
# Output: failList - list of message ids that could not be deleted, along
#                    with a reason for each failure.
#                    Example:
#                        "{1 {database failure}} {2 {other fail reason}}"
#
#############################################################################
proc shadowEventDelete { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set deleteList [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set reason     [ lindex $inputData 2 ]

   set currentTime [ clock seconds ]

   ddl print info "eventmgr: command received from user $operator to delete $deleteList. Reason is: $reason\n"

   #-------------------------------------------------------------------------
   # Let's get a write lock on the database
   #-------------------------------------------------------------------------
   #acquireWriteLock

   #----------------------------------------------------------------------
   # Delete the event id's from the database
   #----------------------------------------------------------------------

   set successList ""
   set failList ""
   set returnList ""

   #
   # Loop through each event id ...
   #

   foreach event $deleteList {

       # NOTE: Put "" around $reason and $operator, in case they are blank

       if { [ catch { deleteEvent $event "$operator" "$reason" $currentTime} \
                                                               result ] } {
          #
          # Failed 
          # ------
          #
          ddl print error "eventmgr: cannot delete event $event from database, reason: $result\n"
          lappend returnList [ list $event "$result" ]
          lappend failList $event

       } else {

          #
          # Success
          # -------
          #
          lappend successList $event
       }
   }

   #-------------------------------------------------------------------------
   # All done. Release the write lock now
   #-------------------------------------------------------------------------
   #releaseWriteLock

   #----------------------------------------------------------------------
   # Always nice to report what happened ...
   #----------------------------------------------------------------------

   if { $failList == "" } {
       ddl print info "eventmgr: delete request successful\n"
   } else {
       if { $successList != "" } {
          ddl print info "eventmgr: successfully deleted $successList\n"
       }
       if { $failList != "" } {
          ddl print info "eventmgr: failed to delete $failList\n"
       }
   }

   ddl print debug "shadowEventDelete: returnList is $returnList\n"

   #----------------------------------------------------------------------
   # Return result    
   #----------------------------------------------------------------------

   return $returnList
}

#############################################################################
#
# proc: shadowEventFix
#
# Shadowmap operation to fix events.
# This routine gets invoked via an "snmp set" to shadowmap ?eventfix.
#
# The specified event ids are marked as "fixed" in the Raima database.
# If an event that is being fixed is currently open and active, then
# the fix action will be sent to the remote agent that generated the
# event also (so that the remote agent can perform any Rule "fix" actions).
#
# Usage: set successList [ shadowEventFix inputData ]
#
# Input: inputData - list of three elements:
#                        <fixList>   - list of message ids to fix
#                        <operator>  - name of operator doing the fix
#                        <reason>    - reason for the fix (can be blank) 
#
# Output: failList - list of message ids that could not be fixed, along
#                    with a reason for each failure.
#                    Example:
#                        "{1 {database failure}} {2 {other fail reason}}"
#
# NOTE: Successfully fixed means we successfully performed this operation
#       in the Raima database.
#
#       It does *not* mean that the fix was successfully performed by the
#       remote agent. No indication is given of the success of the remote
#       agent action.
#
#############################################################################
proc shadowEventFix { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set fixList    [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set reason     [ lindex $inputData 2 ]

   set currentTime [ clock seconds ]

   ddl print info "eventmgr: command received from user $operator to fix $fixList. Reason is: $reason\n"

   #-------------------------------------------------------------------------
   # Let's get a write lock on the database
   #-------------------------------------------------------------------------
   #acquireWriteLock

   #----------------------------------------------------------------------
   # Fix the event id's in the database
   #----------------------------------------------------------------------

   set successList ""
   set failList ""
   set returnList ""
   set agentFixList ""

   #
   # Loop through each event id ...
   #

   foreach event $fixList {

       # NOTE: Put "" around $reason and $operator, in case they are blank

       if { [ catch { fixEvent $event "$operator" "$reason" $currentTime} \
                                                                result ] } {

          #
          # Failed 
          # ------
          #
          ddl print error "eventmgr: cannot fix event $event in database, reason: $result\n"
          lappend returnList [ list $event "$result" ]
          lappend failList $event

       } else {
          #
          # Success
          # -------
          #
          # If we need to send this fix on to the remote agent, do so
          #
          lappend successList $event
         
          set url    [ lindex $result 0 ]
          
          if { $url != "" } {
             ddl print info "eventmgr: forwarding fix of event $event to remote $url\n"
             # sendFixToAgent "$url" "$operator"
             lappend agentFixList $event
          }
       }
   }

   #-------------------------------------------------------------------------
   # All done. Release the write lock now
   #-------------------------------------------------------------------------
   #releaseWriteLock

   #----------------------------------------------------------------------
   # Always nice to report what happened ...
   #----------------------------------------------------------------------

   if { $failList == "" } {
       ddl print info "eventmgr: fix request successful\n"
   } else {
       if { $successList != "" } {
          ddl print info "eventmgr: successfully fixed $successList\n"
       }
       if { $failList != "" } {
          ddl print info "eventmgr: failed to fix $failList\n"
       }
   }

   #----------------------------------------------------------------------
   # Return result    
   #----------------------------------------------------------------------
   ddl print debug "shadowEventFix: returnList is $returnList\n"
   ddl print debug "shadowEventFix: agentFixList is $agentFixList\n"

   return $returnList
}

#############################################################################
#
# proc: sendFixToAgent
#
# Send an fix shadowmap on to the remote agent, that originated the event.
# (So that the remote agent can perform any Rule "fix" actions).
#
# Usage: sendFixToAgent url operator
#
# Input: url - url of node to be "fixed" 
#        operator - name of operator doing the fix
#
# Output: None directly. SNMP command initiated to remote agent.
#
#############################################################################
proc sendFixToAgent { url operator } {
   
   #----------------------------------------------------------------------
   # Build the URL we need
   # (remove any trailing slash added by writeEvent)
   #----------------------------------------------------------------------
   regexp {(.*)/$} $url full url

   if { [ catch { decomposeURL $url } result ] } {
       ddl print warning "failed to forward fix from user $operator to url $url - problem with url : $result \n"
       return
   } else {
      set scheme   [ lindex $result 0 ]
      set net_loc  [ lindex $result 1 ]
      set path     [ lindex $result 2 ]
      set params   [ lindex $result 3 ]
      set query    "fix"
      set fragment [ lindex $result 5 ]

      set fixUrl [ buildURL "$scheme" "$net_loc" "$path" "$params" "$query" \
                                                                "$fragment" ]
      ddl print debug "sendFixToAgent: fixUrl is $fixUrl\n"
   }
  
   #----------------------------------------------------------------------
   # We'll set the fix value to be the operator name, for lack of anything
   # better. The actual value doesn't matter. What we set will simply be
   # echoed back to indicate that the remote fix worked.
   #----------------------------------------------------------------------
   set fixInfo $operator

   #----------------------------------------------------------------------
   # Set the parameters where they can get picked up in the snmp command
   #----------------------------------------------------------------------
   setParameters fixUrl $fixUrl
   setParameters fixCommunity [ getGeneralUser ]
   setParameters fixInfo $fixInfo

   #----------------------------------------------------------------------
   # Create a callback that includes the 
   #
   #              url/operator/fixInfo
   #
   # We need that stuff in the callback, so that we can distinguish
   # different callbacks returning from commands to different urls.
   #----------------------------------------------------------------------
 
   set callback [ list [ list sendFixToAgentCallback $url \
                                        "$operator" "$fixInfo" %result ] ]
 
   #----------------------------------------------------------------------
   # Trigger the remote fix now
   #----------------------------------------------------------------------
 
   if { [ catch { triggerCommandOrMethod fix "" $callback } result ] } {
      ddl print warning "failed to forward fix from user $operator to url $url - problem with snmpset : $result\n"
   }
 
   #----------------------------------------------------------------------
   # Clear parameters now.
   #----------------------------------------------------------------------
   clearParameters

   return
}

#############################################################################
#
# proc: sendFixToAgentCallback
#
# Callback to process response to the "snmp set" to forward an fix to a
# remote Agent.
#
# Usage: sendFixToAgentCallback url operator fixInfo result
#
# Input: url - url that snmp request was sent to
#        operator - name of operator doing thefix 
#        fixInfo - fix information sent in snmp set command
#        result - snmp result
#
# Output: None directly
#
#############################################################################
proc sendFixToAgentCallback { url operator fixInfo result } {

   #ddl print debug "sendFixToAgentCallback: $url $operator $fixInfo $result\n"
 
   switch -- [ lindex $result 0 ] \
      {wait} {
         #----------------------------------------------------------------
         # wait
         #----------------------------------------------------------------
      } \
      {data} {
 
         #----------------------------------------------------------------
         # data
         #----------------------------------------------------------------

         # Success if we get echoed back what we sent
        
         set returnValue [ lindex [ lindex $result 2 ] 0 ]
         if { "$fixInfo" != $returnValue } {
            ddl print warning "failed to forward fix from user $operator to url $url - $returnValue\n"
         } else {
            ddl print info "successfully forwarded fix from user $operator to url $url\n"
         }

      } \
      {error} - \
      default {
         #----------------------------------------------------------------
         # error or something else unexpected
         #----------------------------------------------------------------
         ddl print warning "failed to forward fix from user $operator to url $url - $result\n"
      }
 
   return
}

#############################################################################
#
# proc: shadowEventAck
#
# Shadowmap operation to ack events.
# This routine gets invoked via an "snmp set" to shadowmap ?eventack.
#
# The specified event ids are marked as "acked" in the Raima database.
# If an event that is being acked is currently open and active, then
# the ack action will be sent to the remote agent that generated the
# event also (so that the remote agent can perform any Rule "ack" actions).
#
# Usage: set successList [ shadowEventAck inputData ]
#
# Input: inputData - list of three elements:
#                        <ackList>   - list of message ids to ack
#                        <operator>  - name of operator doing the ack
#                        <reason>    - reason for the ack (can be blank) 
#
# Output: failList - list of message ids that could not be acked, along
#                    with a reason for each failure.
#                    Example:
#                        "{1 {database failure}} {2 {other fail reason}}"
#
# NOTE: Successfully acked means we successfully performed this operation
#       in the Raima database.
#
#       It does *not* mean that the ack was successfully performed by the
#       remote agent. No indication is given of the success of the remote
#       agent action.
#
#############################################################################
proc shadowEventAck { inputData } {
   
   #-------------------------------------------------------------------------
   # Let's get a write lock on the database
   #-------------------------------------------------------------------------
   #acquireWriteLock

   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set ackList    [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set reason     [ lindex $inputData 2 ]

   set currentTime [ clock seconds ]

   ddl print info "eventmgr: command received from user $operator to acknowledge $ackList. Reason is: $reason\n"

   #----------------------------------------------------------------------
   # Ack the event id's in the database
   #----------------------------------------------------------------------

   set successList ""
   set failList ""
   set returnList ""
   set agentAckList ""

   #
   # Loop through each event id ...
   #

   foreach event $ackList {

       # NOTE: Put "" around $reason and $operator, in case they are blank

       if { [ catch { ackEvent $event "$operator" "$reason" $currentTime} \
                                                                result ] } {

          #
          # Failed 
          # ------
          #
          ddl print error "eventmgr: cannot ack event $event in database, reason: $result\n"
          lappend returnList [ list $event "$result" ]
          lappend failList $event

       } else {

          #
          # Success
          # -------
          #
          # If we need to send this ack on to the remote agent, do so
          #
          lappend successList $event
         
          set url    [ lindex $result 0 ]
          
          if { $url != "" } {
             ddl print info "eventmgr: forwarding acknowledge of event $event to remote url $url\n"
             # sendAckToAgent "$url" "$operator" "$reason"
             lappend agentAckList $event
          }
       }
   }

   #----------------------------------------------------------------------
   # Always nice to report what happened ...
   #----------------------------------------------------------------------

   if { $failList == "" } {
       ddl print info "eventmgr: acknowledge request successful\n"
   } else {
       if { $successList != "" } {
          ddl print info "eventmgr: successfully acknowledged $successList\n"
       }
       if { $failList != "" } {
          ddl print info "eventmgr: failed to acknowledge $failList\n"
       }
   }

   #----------------------------------------------------------------------
   # Return result    
   #----------------------------------------------------------------------

   ddl print debug "shadowEventAck: returnList is $returnList\n"
   ddl print debug "shadowEventAck: agentAckList is $agentAckList\n"

   #-------------------------------------------------------------------------
   # All done. Release the write lock now
   #-------------------------------------------------------------------------
   #releaseWriteLock

   return $returnList
}

#############################################################################
#
# proc: sendAckToAgent
#
# Send an ack shadowmap on to the remote agent, that originated the event.
# (So that the remote agent can perform any Rule "ack" actions).
#
# Usage: sendAckToAgent url operator reason
#
# Input: url - url of node to be acked
#        operator - name of operator doing the ack
#        reason - reason for the ack
#
# Output: None directly. SNMP command initiated to remote agent.
#
#############################################################################
proc sendAckToAgent { url operator reason } {
   
   #----------------------------------------------------------------------
   # Build the URL we need
   # (remove any trailing slash added by writeEvent)
   #----------------------------------------------------------------------
   regexp {(.*)/$} $url full url

   if { [ catch { decomposeURL $url } result ] } {
       ddl print warning "failed to forward acknowledgement from user $operator to url $url - problem with url : $result \n"
       return
   } else {
      set scheme   [ lindex $result 0 ]
      set net_loc  [ lindex $result 1 ]
      set path     [ lindex $result 2 ]
      set params   [ lindex $result 3 ]
      set query    "acknowledgement"
      set fragment [ lindex $result 5 ]

      set ackUrl [ buildURL "$scheme" "$net_loc" "$path" "$params" "$query" \
                                                                "$fragment" ]
      ddl print debug "sendAckToAgent: ackUrl is $ackUrl\n"
   }
  
   #----------------------------------------------------------------------
   # Build the ack information we need
   #----------------------------------------------------------------------

   set ackInfo [ list $operator $reason EVENTMGR ]

   #----------------------------------------------------------------------
   # Set the parameters where they can get picked up in the snmp command
   #----------------------------------------------------------------------
   setParameters ackUrl $ackUrl
   setParameters ackCommunity [ getGeneralUser ]
   setParameters ackInfo $ackInfo

   #----------------------------------------------------------------------
   # Create a callback that includes the 
   #
   #              url/operator/ackInfo
   #
   # We need that stuff in the callback, so that we can distinguish
   # different callbacks returning from commands to different urls.
   #----------------------------------------------------------------------
 
   set callback [ list [ list sendAckToAgentCallback $url \
                                        "$operator" "$ackInfo" %result ] ]
 
   #----------------------------------------------------------------------
   # Trigger the remote ack now
   #----------------------------------------------------------------------
 
   if { [ catch { triggerCommandOrMethod ack "" $callback } result ] } {
      ddl print warning "failed to forward acknowledgment from user $operator to url $url - problem with snmpset : $result\n"
   }
 
   #----------------------------------------------------------------------
   # Clear parameters now.
   #----------------------------------------------------------------------
   clearParameters

   return
}

#############################################################################
#
# proc: sendAckToAgentCallback
#
# Callback to process response to the "snmp set" to forward an ack to a
# remote Agent.
#
# Usage: sendAckToAgentCallback url operator ackInfo result
#
# Input: url - url that snmp request was sent to
#        operator - name of operator doing the ack
#        ackInfo - ack information sent in snmp set command
#        result - snmp result
#
# Output: None directly
#
#############################################################################
proc sendAckToAgentCallback { url operator ackInfo result } {

   #ddl print debug "sendAckToAgentCallback: $url $operator $ackInfo $result\n"
 
   switch -- [ lindex $result 0 ] \
      {wait} {
         #----------------------------------------------------------------
         # wait
         #----------------------------------------------------------------
      } \
      {data} {
 
         #----------------------------------------------------------------
         # data
         #----------------------------------------------------------------

         # Success if we get echoed back what we sent
        
         set returnValue [ lindex [ lindex $result 2 ] 0 ]
         if { "$ackInfo" != $returnValue } {
            ddl print warning "failed to forward acknowledgement from user $operator to url $url -- $returnValue\n"
         } else {
            ddl print info "successfully forwarded acknowledgement from user $operator to url $url\n"
         }

      } \
      {error} - \
      default {
         #----------------------------------------------------------------
         # error or something else unexpected
         #----------------------------------------------------------------
         ddl print warning "failed to forward acknowledgement from user $operator to url $url -- $result\n"
      }
 
   return
}

#############################################################################
#
# proc: shadowEventUnack
#
# Shadowmap operation to "unack" events.
# This routine gets invoked via an "snmp set" to shadowmap ?eventunack.
#
# The specified event ids are "unacked" in the Raima database.
# If an event that is being unacked is currently open and active, then
# the unack action will be sent to the remote agent that generated the
# event also.
#
# Usage: set successList [ shadowEventUnack inputData ]
#
# Input: inputData - list of three elements:
#                        <unackList>   - list of message ids to unack
#                        <operator>  - name of operator doing the unack
#                        <reason>    - reason for the unack (can be blank) 
#
# Output: failList - list of message ids that could not be unacked, along
#                    with a reason for each failure.
#                    Example:
#                        "{1 {database failure}} {2 {other fail reason}}"
#
# NOTE: Successfully unacked means we successfully performed this operation
#       in the Raima database.
#
#       It does *not* mean that the unack was successfully performed by the
#       remote agent. No indication is given of the success of the remote
#       agent action.
#
#############################################################################
proc shadowEventUnack { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set unackList    [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set reason     [ lindex $inputData 2 ]

   set currentTime [ clock seconds ]

   ddl print info "eventmgr: command received from user $operator to clear acknowledgement of $unackList. Reason is: $reason\n"

   #-------------------------------------------------------------------------
   # Let's get a write lock on the database
   #-------------------------------------------------------------------------
   #acquireWriteLock

   #----------------------------------------------------------------------
   # Unack the event id's in the database
   #----------------------------------------------------------------------

   set successList ""
   set failList ""
   set returnList ""
   set agentUnackList ""

   #
   # Loop through each event id ...
   #

   foreach event $unackList {

       # NOTE: Put "" around $reason and $operator, in case they are blank

       # NOTE: THIS FUNCTION IS NOT IMPLEMENTED IN RAIMA LIBRARIES. THIS 
       #       STUFF IS JUST HERE AS A FUTURE HOOK. SEE pkgeventmgr.c.

       if { [ catch { unackEvent $event "$operator" "$reason" $currentTime} \
                                                                result ] } {

          #
          # Failed 
          # ------
          #
          ddl print error "eventmgr: cannot clear acknowledgement of event $event in database, reason: $result\n"
          lappend returnList [ list $event "$result" ]
          lappend failList $event

       } else {

          #
          # Success
          # -------
          #
          # If we need to send this unack on to the remote agent, do so
          #
          lappend successList $event
         
          set url    [ lindex $result 0 ]
          
          if { $url != "" } {
             ddl print info "eventmgr: forwarding clear acknowledgement of event $event to remote url $url\n"
             sendUnackToAgent "$url" "$operator" "$reason"
             lappend agentUnackList $event
          }
       }
   }

   #-------------------------------------------------------------------------
   # All done. Release the write lock now
   #-------------------------------------------------------------------------
   #releaseWriteLock

   #----------------------------------------------------------------------
   # Always nice to report what happened ...
   #----------------------------------------------------------------------

   if { $failList == "" } {
       ddl print info "eventmgr: clear acknowledgement request successful\n"
   } else {
       if { $successList != "" } {
          ddl print info "eventmgr: successfully cleared acknowledgement for $successList\n"
       }
       if { $failList != "" } {
          ddl print info "eventmgr: failed to clear acknowledgement for $failList\n"
       }
   }

   #----------------------------------------------------------------------
   # Return result    
   #----------------------------------------------------------------------

   ddl print debug "shadowEventUnack: returnList is $returnList\n"
   ddl print debug "shadowEventUnack: agentUnackList is $agentUnackList\n"

   return $returnList
}

#############################################################################
#
# proc: sendUnackToAgent
#
# Send an unack shadowmap on to the remote agent, that originated the event.
#
# Usage: sendUnackToAgent url operator reason
#
# Input: url - url of node to be unacked
#        operator - name of operator doing the unack
#        reason - reason for the unack
#
# Output: None directly. SNMP command initiated to remote agent.
#
#############################################################################
proc sendUnackToAgent { url operator reason } {
   
   #----------------------------------------------------------------------
   # Build the URL we need
   # (remove any trailing slash added by writeEvent)
   #----------------------------------------------------------------------
   regexp {(.*)/$} $url full url

   if { [ catch { decomposeURL $url } result ] } {
       ddl print warning "failed to forward clear acknowledgment from user $operator to url $url - problem with url : $result \n"
       return
   } else {
      set scheme   [ lindex $result 0 ]
      set net_loc  [ lindex $result 1 ]
      set path     [ lindex $result 2 ]
      set params   [ lindex $result 3 ]
      set query    "unacknowledge"
      set fragment [ lindex $result 5 ]

      set unackUrl [ buildURL "$scheme" "$net_loc" "$path" "$params" "$query" \
                                                                "$fragment" ]
      ddl print debug "sendUnackToAgent: unackUrl is $unackUrl\n"
   }
  
   #----------------------------------------------------------------------
   # Build the unack information we need
   #----------------------------------------------------------------------

   set unackInfo [ list $operator $reason EVENTMGR ]

   #----------------------------------------------------------------------
   # Set the parameters where they can get picked up in the snmp command
   #----------------------------------------------------------------------
   setParameters unackUrl $unackUrl
   setParameters unackCommunity [ getGeneralUser ]
   setParameters unackInfo $unackInfo

   #----------------------------------------------------------------------
   # Create a callback that includes the 
   #
   #              url/operator/unackInfo
   #
   # We need that stuff in the callback, so that we can distinguish
   # different callbacks returning from commands to different urls.
   #----------------------------------------------------------------------
 
   set callback [ list [ list sendUnackToAgentCallback $url \
                                        "$operator" "$unackInfo" %result ] ]
 
   #----------------------------------------------------------------------
   # Trigger the remote unack now
   #----------------------------------------------------------------------
 
   if { [ catch { triggerCommandOrMethod unack "" $callback } result ] } {
      ddl print warning "failed to forward clear acknowledgment from user $operator to url $url - problem with snmpset : $result\n"
   }
 
   #----------------------------------------------------------------------
   # Clear parameters now.
   #----------------------------------------------------------------------
   clearParameters

   return
}

#############################################################################
#
# proc: sendUnackToAgentCallback
#
# Callback to process response to the "snmp set" to forward an unack to a
# remote Agent.
#
# Usage: sendUnackToAgentCallback url operator unackInfo result
#
# Input: url - url that snmp request was sent to
#        operator - name of operator doing the unack
#        unackInfo - unack information sent in snmp set command
#        result - snmp result
#
# Output: None directly
#
#############################################################################
proc sendUnackToAgentCallback { url operator unackInfo result } {

   #ddl print debug "sendUnackToAgentCallback: $url $operator $unackInfo $result\n"
 
   switch -- [ lindex $result 0 ] \
      {wait} {
         #----------------------------------------------------------------
         # wait
         #----------------------------------------------------------------
      } \
      {data} {
 
         #----------------------------------------------------------------
         # data
         #----------------------------------------------------------------

         # Success if we get echoed back what we sent
        
         set returnValue [ lindex [ lindex $result 2 ] 0 ]
         if { "$unackInfo" != $returnValue } {
            ddl print warning "failed to forward clear acknowledgement from user $operator to url $url -- $returnValue\n"
         } else {
            ddl print info "successfully forwarded clear acknowledgement from user $operator to url $url\n"
         }

      } \
      {error} - \
      default {
         #----------------------------------------------------------------
         # error or something else unexpected
         #----------------------------------------------------------------
         ddl print warning "failed to forward clear acknowledgement from user $operator to url $url -- $result\n"
      }
 
   return
}


#############################################################################
#
# proc: sendActionToAgentCallback
#
# Callback to process response to the "snmp set" to forward an action to a
# remote Agent.
#
# Usage: sendActionToAgentCallback url unackInfo result
#
# Input: url - url that snmp request was sent to
#        unackInfo - unack information sent in snmp set command
#        result - snmp result
#
# Output: None directly
#
#############################################################################
proc sendActionToAgentCallback { url ackInfo result evid } {

   ddl print debug "sendActionToAgentCallback: $url $ackInfo $result\n"
 
   switch -- [ lindex $result 0 ] \
      {wait} {
         #----------------------------------------------------------------
         # wait
         #----------------------------------------------------------------
      } \
      {data} {
 
         #----------------------------------------------------------------
         # data
         #----------------------------------------------------------------

         # Success if we get echoed back what we sent
        
         set returnValue [ lindex [ lindex $result 2 ] 0 ]
         if { "$ackInfo" != $returnValue } {
            ddl print warning "failed to forward action to url $url -- $returnValue\n"
         } else {
            actionStateUpdate $evid 2
            ddl print info "successfully forwarded action to url $url\n"
         }

      } \
      {error} - \
      default {
         #----------------------------------------------------------------
         # error or something else unexpected
         #----------------------------------------------------------------
         ddl print warning "failed to forward action to url $url -- $result\n"
      }
   
   return
}

proc shadowEventActionNameUpdate { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set eventID    [ lindex $inputData 0 ]
   set actionName [ lindex $inputData 1 ]

   ddl print debug "shadowEventActionNameUpdate: input is $inputData\n"
   if { [ catch {  actionNameUpdate $eventID $actionName} \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot update action name $actionName for event $event, reason: $result\n"
   }

   return
}

proc shadowEventRunAlarmAction { inputData } {

   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------
   set evid    [ lindex $inputData 0 ]

   actionStateUpdate $evid 2

   set returnvalue ""

   return $returnvalue

   # following codes, not in use, just for future reference

   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set eventID    [ lindex $inputData 0 ]
  

   ddl print error "shadowEventRunAlarmAction: input is $inputData ffff\n"
   if { [ catch {  getEventAttributes $eventID } \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot retrieve alarm attributes for event $eventID, reason: $result\n"

   } else {
      ddl print error "shadowEventRunAlarmAction $result"

      set urlparts [ split [ lindex $result 0 ] "#" ]
      set firstpart [ lindex $urlparts 0 ]
      set secondpart [ lindex [ split [ lindex $urlparts 1 ] / ] 0 ]
      set url "${firstpart}?alarmdelayedaction#${secondpart}"

      set action [ lindex $result 1 ]
      ddl print error "shadowEventRunAlarmAction $url $action"

     #----------------------------------------------------------------------
     # Set the parameters where they can get picked up in the snmp command
     #----------------------------------------------------------------------
     setParameters actionUrl $url
     setParameters actionCommunity [ getGeneralUser ]
     setParameters actionInfo $action

     #----------------------------------------------------------------------
     # Create a callback that includes the 
     #
     #              url/actionInfo
     #
     # We need that stuff in the callback, so that we can distinguish
     # different callbacks returning from commands to different urls.
     #----------------------------------------------------------------------
 
     set callback [ list [ list sendActionToAgentCallback $url \
                                        "$action" %result $eventID] ]
 
     #----------------------------------------------------------------------
     # Trigger the remote unack now
     #----------------------------------------------------------------------
 
     if { [ catch { triggerCommandOrMethod action "" $callback } result ] } {
        ddl print warning "failed to forward action from to url $url - problem with snmpset : $result\n"
     }
 
     #----------------------------------------------------------------------
     # Clear parameters now.
     #----------------------------------------------------------------------
     clearParameters
   }

   return $returnvalue
   
}

proc shadowEventNoteAppend { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set eventID    [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set note       [ lindex $inputData 2 ]
   set locale       [ lindex $inputData 3 ]

   ddl print debug "shadowEventNoteAppend: input is $inputData\n"
   set currentTime [ clock seconds ]
   if { [ catch {  noteAppend $eventID $currentTime $operator $note $locale} \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot append note to event $event, reason: $result\n"
   }

   return
}

proc shadowEventNotesGet { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set eventID    [ lindex $inputData 0 ]
   set locale     [ lindex $inputData 1 ]

   ddl print debug "shadowEventNotesGet: input is $inputData\n"
   if { [ catch {  getNote $eventID $locale} \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot get notes for event $event, reason: $result\n"

   }
   return $result
}

proc shadowEventSuggestedFixAppend { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set propertyURL    [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set fix        [ lindex $inputData 2 ]
   set locale     [ lindex $inputData 3 ]

   set currentTime [ clock seconds ]

   ddl print debug "shadowEventSuggestedFixAppend: input is $inputData\n"
   if { [ catch {  suggestedFixAppend $propertyURL $currentTime $operator $fix  $locale} \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot append fix to oroperty  $propertyURL, reason: $result\n"

   }
   return
   
}

proc shadowEventSuggestedFixesGet { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set propertyURL    [ lindex $inputData 0 ]
   set locale   [ lindex $inputData 1 ]

   ddl print debug "shadowEventSuggestedFixesGet: input is $inputData\n"
 
   if { [ catch {  getSuggestedFix $propertyURL $locale} \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr: cannot get fixes for property URL $propertyURL and locale $locale , reason: $result\n"

   }

   return $result
}

proc shadowEventClosedEventsDelete { inputData } {
   
   #----------------------------------------------------------------------
   # Parse input data
   #----------------------------------------------------------------------

   set host       [ lindex $inputData 0 ]
   set operator   [ lindex $inputData 1 ]
   set reason     [ lindex $inputData 2 ]
   set currentTime [ clock seconds ]

   ddl print debug "shadowEventClosedEventsDelete: input is $inputData\n"
   if { [ catch {  closedEventsDelete "$operator" "$reason"  $host $currentTime } \
                                                result ] } {
       #
       # Failed 
       # ------
       #
       ddl print error "eventmgr:could not delete closed events for host $host because, reason: $result\n"

   }
   
   return
}
