# -*- Tcl -*-

#
# Create a window to hold the keytab information.
#
# The "w" argument is the root window path to use.  It defaults to ".kt"
#
# The "file" argument is the keytab filename to act on.  If this is "", it
# will act on the default keytab. [untested]
#
# The "lb" argument is a listbox we can snag principal names from when
# the "add" button is clicked.  If this is not provided the add button will
# not be enabled.
#
proc kt_create { { w ".kt" } { lb "" } } {
    if { $w == "" } {
	set w ".kt"
    }

    if {[winfo exists $w]} {
	return $w
    }

    toplevel $w
    wm title $w "Keytab Editing"

    frame $w.list

    scrollbar $w.list.sb -orient vertical -relief sunken \
	    -command "$w.list.lb yview"

    listbox $w.list.lb -selectmode extended -width 40 -relief sunken \
	    -yscrollcommand "$w.list.sb set"

    pack $w.list.sb -side right -expand yes -fill both
    pack $w.list.lb -side left -expand yes -fill both
    
    frame $w.bts
    button $w.bts.close -text "Done" -command "destroy $w"
    if { $lb != "" } {
	button $w.bts.add -text "Add Principals" -command "kt_add $w $lb"
    }
    button $w.bts.del -text "Delete Principals" -command "kt_del $w"

    if { $lb != "" } {
	pack $w.bts.close $w.bts.add $w.bts.del -side left
    } else {
	pack $w.bts.close $w.bts.del -side left
    }

    pack $w.list $w.bts -side top

    return $w
}

#
# delete the selected principal(s) from the keytab.
#
# After this is done, refresh the keytab listing.
#
# "w" is the keytab's base window, from which we will extract the entries.
#
proc kt_del { w } {
    set wr _ktlist_[string range $w 1 end]
    set wr_file ${wr}_file

    global $wr $wr_file

    upvar #0 $wr _wr
    upvar #0 $wr_file _wr_file

    set farg ""
    if { $_wr_file != "" } {
	set farg [list -keytab $_wr_file]
    }

    set cursel [$w.list.lb curselection]

    if { [llength $cursel] == 0 } {
	tk_dialog .dialog {Error} "No principals selected." "" 0 Ok
	return
    }

    foreach sel $cursel {
	foreach i $_wr {
	    set kvno [lindex $i 0]
	    set p [lindex $i 2]
	    set selpv [split [$w.list.lb get $sel] " ()"]
	    set selp [lindex $selpv 0]
	    set selv [lindex $selpv 2]

	    if { $p == $selp && $kvno == $selv} {
		eval [concat kadm5_ktremove $farg $p $kvno]
		break;
	    }
	}
    }

    set _wr [kadm5_ktlist $_wr_file]

    kt_update_lb $w.list.lb $_wr
}

proc kt_add { w lb } {
    set wr _ktlist_[string range $w 1 end]
    set wr_file ${wr}_file

    global $wr $wr_file

    upvar #0 $wr _wr
    upvar #0 $wr_file _wr_file

    set farg ""
    if { $_wr_file != "" } {
	set farg [list -keytab $_wr_file]
    }

    set cursel [$lb curselection]

    if { [llength $cursel] == 0 } {
	tk_dialog .dialog {Error} "No principals selected." "" 0 Ok
	return
    }

    #
    # if the principal exists in the keytab, only delete it if the version
    # we are inserting equals the version in the keytab
    #
    foreach sel $cursel {
	set selp [$lb get $sel]
	set pvno ""

	foreach i $_wr {
	    set kvno [lindex $i 0]
	    set p [lindex $i 2]

	    if { $p == $selp } {
		if { $pvno == "" } {
		    set pvno [expr [lindex [kadm5_getprinc $p] 8] + 1]
		}
		if { $pvno == $kvno } {
		    eval [concat kadm5_ktremove $farg $p $kvno]
		    break;
		}
	    }
	}
	eval [concat kadm5_ktadd $farg $selp]
    }

    set _wr [kadm5_ktlist $_wr_file]

    kt_update_lb $w.list.lb $_wr
}

#
# Read a keytab "file" into window "w", destroying what was there before.
#
# The "w" argument is the root window path to use.  It defaults to ".kt"
#
# The "file" argument is the keytab filename to act on.  If this is "", it
# will act on the default keytab. [untested]
#
proc kt_populate { { w ".kt" } { file "" } } {
    if { $w == "" } {
	set w ".kt"
    }
    set wr _ktlist_[string range $w 1 end]
    set wr_file ${wr}_file

    global $wr $wr_file

    upvar #0 $wr _wr
    upvar #0 $wr_file _wr_file

    set _wr [kadm5_ktlist $file]
    set _wr_file $file

    kt_update_lb $w.list.lb $_wr
}

proc kt_update_lb { lb pl } {
    $lb delete 0 end
    foreach i $pl {
	set p [lindex $i 2]
	set kvno [lindex $i 0]
	$lb insert end "$p ($kvno)"
    }
}

#
# Create a new keytab "file" using window "w"
#
# The "w" argument is the root window path to use.  It defaults to ".kt"
#
# The "file" argument is the keytab filename to act on.  If this is "", it
# will act on the default keytab. [untested]
#
proc kt_new { { w ".kt" } { file "" } } {
    if { $w == "" } {
	set w ".kt"
    }
    set wr _ktlist_[string range $w 1 end]
    set wr_file ${wr}_file

    global $wr $wr_file

    upvar #0 $wr _wr
    upvar #0 $wr_file _wr_file

    set _wr {}
    set _wr_file $file

    kt_update_lb $w.list.lb $_wr
}
