#!/bin/sh
#
# @(#)mcp-d.prc	1.3 01/02/14
# Copyright (c) 02/14/01 Sun Microsystems, Inc. All Rights Reserved.
#

method mcpTriggerCommand { spec } {
    ddl print info "mcpTriggerCommand - spec=$spec\n"

    #
    # check for outstanding operation
    #
    if { [ lookup -d "false" mcpstatus outstanding ] == "true" } {
	return [ list "error" "" "outstanding MCP job already exists" ]
    }

    #
    # place spec in params and trigger operation
    #
    setParameters params $spec

    if { [ catch { triggerCommandOrMethod operation "" {{mcpOperationCallback %result}} getNodeParam } result ] } {
        #
        # process error
        #
        mcpOperationCallback [ list "error" "" $result ]
    }

    #
    # set interim result
    #
    set id [ lindex $result 1 ]
    define mcpstatus $id $result
    define mcpstatus outstanding "true"
    ddl print info "mcpTriggerCommand - result=$result\n"
    return $result
}

method mcpOperationCallback { arc } {
    ddl print info "mcpOperationCallback - arc=$arc\n"
    #
    # determine id
    #
    set id [ lindex $arc 1 ]

    #
    # store result
    #
    define mcpstatus $id $arc

    #
    # log any problems
    #
    if { [ lindex $arc 0 ] == "error" } {
    	ddl print warning "mcpOperationCallback - error: [ lindex $arc 2 ]\n"
	clearParameters params
	define mcpstatus outstanding "false"
	return
    }

    if { [ lindex $arc 0 ] == "data" } {
	if { [ lindex $arc 2 ] == "success" } {
	    if { [ toe_name [ toe_superior ] ] == "propagate" } {
		set result [ mcpDoModuleReload [ getParameter params ] ]
		set arc [ list "data" $id $result ]
		define mcpstatus $id $arc
	    }
	} else {
	    ddl print warning "mcpOperationCallback - error: [ lindex $arc 2 ]\n"
	}
	clearParameters params
	define mcpstatus outstanding "false"
    }
}

method mcpQueryResult { id } {
    ddl print info "mcpQueryResult - id=$id\n"
    return [ lookup mcpstatus $id ]
}

method showModuleEntries {} {
    set result ""
    set target [ locate .iso*modules.mcp.moduleRegistryTable.moduleRegistryEntry ]
    foreach module [ toe_send $target entries modReg ] {
	set params [ toe_send $target lookup -d "" modReg $module ]
	if { $params == "" } {
	    set params "{}"
	}
	set result "$module null $result"
    }
    return $result
}

method mcpDoModuleReload { options } {
    ddl print info "mcpDoModuleReload: options=$options\n"
    #
    # options are:	A,B,C,D,E
    # where:
    #		A = dat propagate	(0=always, 1=if not loaded)
    #		B = load		(0=always, 1=if already loaded)
    #		C = parameters		(0=reference, 1=target)
    #		D = security		(0=reference, 1=target)
    #		E = schedule		(0=reference, 1=target)
    #
    # This method is concerned with B, C and E.  All others are handled
    # by the propagation scripts
    #
    set parts [ split $options "," ]
    set loadFlag [ lindex $parts 4 ]
    set paramFlag [ lindex $parts 5 ]
    set schedFlag [ lindex $parts 7 ]

    #
    # locate module loader
    #
    set moduleloader [ locate .iso*mibman.modules ]

    #
    # load reference module information
    #
    import interface refModules "base-modules-d.dat.MCP"

    #
    # assume success until one module fails
    #
    set status "success"

    #
    # process modules one-by-one
    #
    sliceforeach name refSpec refModules {
	#
	# get params
	#
	set refParams [ lindex $refSpec 3 ]

	#
	# assume reload will occur
	#
        set reloadFlag true

	#
	# get current load params (if any)
	#
	set curSpec [ toe_send $moduleloader lookup -d "" module $name ]
	set curParams [ lindex $curSpec 3 ]
	if { $curParams == "" } {
	    #
	    # module not currently loaded
	    #
	    if { $loadFlag == 1 } {
		#
		# skip this module
		#
		continue
	    } else {
		#
		# all params must come from reference
		#
		set curParams $refParams
		set reloadFlag false
	    }
	}

	#
	# process the parameters
	#
	set newParams [ mcpProcessParameters $curParams $refParams $paramFlag $schedFlag $reloadFlag ]

	#
	# reload the module with the new params
	#
	if { [ toe_csend result $moduleloader quickLoad $newParams "" ] } {
	    #
	    # problem loading module
	    #
	    ddl print warning "mcpDoModuleReload: module reload failed\n"
	    ddl print warning "mcpDoModuleReload: $result\n"

	    if { "$status" == "success" } {
		set status "error loading module $name: $result"
	    } else {
		append status "\n" "error loading module $name: $result"
	    }
	}
    }

    undefine refModules

    return $status
}


method mcpProcessParameters { curParams refParams paramFlag schedFlag reloadFlag } {
    #
    # ensure dicts are clean
    #
    undefine _refParams
    undefine _curParams
    undefine _newParams

    #
    # put mod params in _refParams slice
    #
    import string _refParams $refParams

    #
    # put current params in _curParams slice
    #
    import string _curParams $curParams

    #
    # perform merging...
    #

    #
    # get general params
    #
    if { $paramFlag == 0 } {
	#
	# take params from reference
	#
	slicecopy _refParams _newParams
    } else {
	#
	# take params from current
	#
	slicecopy _curParams _newParams
    }

    #
    # get schedule params
    #
    if { $schedFlag == 0 } {
	#
	# take schedule from reference
	#
	set loadtimewindow [ lookup -d "" _refParams loadtimewindow ]
	set enabletimewindow [ lookup -d "" _refParams enabletimewindow ]
    } else {
	#
	# take schedule from current
	#
	set loadtimewindow [ lookup -d "" _curParams loadtimewindow ]
	set enabletimewindow [ lookup -d "" _curParams enabletimewindow ]
    }
    if { $loadtimewindow != "" } {
        define _newParams loadtimewindow $loadtimewindow
    }
    if { $enabletimewindow != "" } {
        define _newParams enabletimewindow $enabletimewindow
    }

    #
    # ensure reload is done
    #
    define _newParams _RELOAD $reloadFlag

    #
    # export new params into string
    #
    export string _newParams newParams

    #
    # clean up
    #
    undefine _curParams
    undefine _refParams
    undefine _newParams

    return $newParams
}
