# This is the scheduled procedure for keepalive

proc keepalive_check_monitors {} {
    ns_share keepalive_monitor_list

    if {[keepalive_debug]} {
	ns_log Notice "starting checks... keepalive"
    }

    foreach keepalive_monitor $keepalive_monitor_list {
	set result [check_monitor $keepalive_monitor]

	# A result comes back as a list of 
	# two things:
	# - a boolean that says whether the site was reachable or not.
	# - the actual page we got returned (this is for error messages)
	if {[keepalive_debug]} {
	    ns_log Notice "[ns_set get $keepalive_monitor name] got result [lindex $result 0]"
	}	

	# If we fail
	if {![lindex $result 0]} {
	    # Decrement the counter
	    set counter [ns_set get $keepalive_monitor counter]
	    incr counter -1
	    ns_set update $keepalive_monitor counter $counter
	    if {[keepalive_debug]} {
		ns_log Notice "failure on [ns_set get $keepalive_monitor name]. Counter down to $counter"
	    }

	    # If we've gone through all the tries for this one
	    if {$counter == 0} {
		# reset the counter
		ns_set update $keepalive_monitor counter [ns_set get $keepalive_monitor n_tries]

		# Perform the kill action
		
		set action [ns_set get $keepalive_monitor failure_action]
		set supplemental_note ""
		if {$action != ""} {
		    # This is nasty, but we must first build the 
		    # exec statement
		    if [catch { eval "exec $action" } errmsg] {
			if {[keepalive_debug]} {
			    ns_log Notice "failed to exec $action : $errmsg"
			}
			set supplemental_note "\n\nOuch! the exec failed!!!"
		    }
		}
		
		# Send email
		notify_admins $keepalive_monitor "admin_list" "failure on [ns_set get $keepalive_monitor name]" \
			[ka_long_message [ns_set get $keepalive_monitor name] [lindex $result 1] 0 [ns_set get $keepalive_monitor failure_action] $supplemental_note]

		# to pagers too.
		#notify_admins $keepalive_monitor "pager_list" "failure on [ns_set get $keepalive_monitor name]" \
			#[ka_short_message [ns_set get $keepalive_monitor name] [lindex $result 1] 0 [ns_set get $keepalive_monitor failure_action]]

} else {
		# failure but we're still decrementing the counter
		# and need not take action
                if { [ns_set get $keepalive_monitor counter] < [ns_set get $keepalive_monitor notify_threshold] } {
		    notify_admins $keepalive_monitor "admin_list" "failure on [ns_set get $keepalive_monitor name]" \
			[ka_long_message [ns_set get $keepalive_monitor name] [lindex $result 1] [ns_set get $keepalive_monitor counter] ""]

		    # to pagers too.
		    #notify_admins $keepalive_monitor "pager_list" "failure on [ns_set get $keepalive_monitor name]" \
			#[ka_short_message [ns_set get $keepalive_monitor name] [lindex $result 1] [ns_set get $keepalive_monitor counter] ""]
		}
	    }
	} else {
	    # We succeed! 
	    # reset the counter
	    ns_set update $keepalive_monitor counter [ns_set get $keepalive_monitor n_tries]
	}
    }
}
	    
proc check_monitor {one_monitor} {
    if {[catch {set page [ns_httpget [ns_set get $one_monitor url] [keepalive_timeout]]} errmsg]} {
	return [list 0 $errmsg]
    }
    
    # let's look for the expected result being the first thing in the result
    # (this gets around the newline problem) -- philg 12/10/98
    if {[string first [ns_set get $one_monitor expected_result] $page]==0} {
	return [list 1 $page]
    } else {
	return [list 0 $page]
    }
}

proc notify_admins {one_monitor which_list subject message} {
    set admins [ns_set get $one_monitor $which_list]
    foreach admin $admins {
	set email_action {ns_sendmail $admin [keepalive_email] $subject $message}
	if {[catch $email_action errmsg]} {
	    ns_log Error "could not send email to $admin !!"
	}
    }
}
