# git-gui remote management
# Copyright (C) 2006, 2007 Shawn Pearce

set some_heads_tracking 0;  # assume not

proc is_tracking_branch {name} {
	global tracking_branches
	foreach spec $tracking_branches {
		set t [lindex $spec 0]
		if {$t eq $name || [string match $t $name]} {
			return 1
		}
	}
	return 0
}

proc all_tracking_branches {} {
	global tracking_branches

	set all [list]
	set pat [list]
	set cmd [list]

	foreach spec $tracking_branches {
		set dst [lindex $spec 0]
		if {[string range $dst end-1 end] eq {/*}} {
			lappend pat $spec
			lappend cmd [string range $dst 0 end-2]
		} else {
			lappend all $spec
		}
	}

	if {$pat ne {}} {
		set fd [git_read [concat for-each-ref --format=%(refname) $cmd]]
		while {[gets $fd n] > 0} {
			foreach spec $pat {
				set dst [string range [lindex $spec 0] 0 end-2]
				set len [string length $dst]
				if {[string equal -length $len $dst $n]} {
					set src [string range [lindex $spec 2] 0 end-2]
					set spec [list \
						$n \
						[lindex $spec 1] \
						$src[string range $n $len end] \
						]
					lappend all $spec
				}
			}
		}
		close $fd
	}

	return [lsort -index 0 -unique $all]
}

proc load_all_remotes {} {
	global repo_config
	global all_remotes tracking_branches some_heads_tracking
	global remote_url

	set some_heads_tracking 0
	set all_remotes [list]
	set trck [list]

	set rh_str refs/heads/
	set rh_len [string length $rh_str]
	set rm_dir [gitdir remotes]
	if {[file isdirectory $rm_dir]} {
		set all_remotes [glob \
			-types f \
			-tails \
			-nocomplain \
			-directory $rm_dir *]

		foreach name $all_remotes {
			catch {
				set fd [safe_open_file [file join $rm_dir $name] r]
				while {[gets $fd line] >= 0} {
					if {[regexp {^URL:[ 	]*(.+)$} $line line url]} {
						set remote_url($name) $url
						continue
					}
					if {![regexp {^Pull:[ 	]*([^:]+):(.+)$} \
						$line line src dst]} continue
					if {[string index $src 0] eq {+}} {
						set src [string range $src 1 end]
					}
					if {![string equal -length 5 refs/ $src]} {
						set src $rh_str$src
					}
					if {![string equal -length 5 refs/ $dst]} {
						set dst $rh_str$dst
					}
					if {[string equal -length $rh_len $rh_str $dst]} {
						set some_heads_tracking 1
					}
					lappend trck [list $dst $name $src]
				}
				close $fd
			}
		}
	}

	foreach line [array names repo_config remote.*.url] {
		if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
		lappend all_remotes $name
		set remote_url($name) $repo_config(remote.$name.url)

		if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
			set fl {}
		}
		foreach line $fl {
			if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
			if {[string index $src 0] eq {+}} {
				set src [string range $src 1 end]
			}
			if {![string equal -length 5 refs/ $src]} {
				set src $rh_str$src
			}
			if {![string equal -length 5 refs/ $dst]} {
				set dst $rh_str$dst
			}
			if {[string equal -length $rh_len $rh_str $dst]} {
				set some_heads_tracking 1
			}
			lappend trck [list $dst $name $src]
		}
	}

	set tracking_branches [lsort -index 0 -unique $trck]
	set all_remotes [lsort -unique $all_remotes]
}

proc add_fetch_entry {r} {
	global repo_config
	set remote_m .mbar.remote
	set fetch_m $remote_m.fetch
	set prune_m $remote_m.prune
	set remove_m $remote_m.remove
	set enable 0
	if {![catch {set a $repo_config(remote.$r.url)}]} {
		if {![catch {set a $repo_config(remote.$r.fetch)}]} {
			set enable 1
		}
	} else {
		catch {
			set fd [safe_open_file [gitdir remotes $r] r]
			while {[gets $fd n] >= 0} {
				if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
					set enable 1
					break
				}
			}
			close $fd
		}
	}

	if {$enable} {
		make_sure_remote_submenues_exist $remote_m

		$fetch_m add command \
			-label $r \
			-command [list fetch_from $r]
		$prune_m add command \
			-label $r \
			-command [list prune_from $r]
		$remove_m add command \
			-label $r \
			-command [list remove_remote $r]
	}
}

proc add_push_entry {r} {
	global repo_config
	set remote_m .mbar.remote
	set push_m $remote_m.push
	set enable 0
	if {![catch {set a $repo_config(remote.$r.url)}]} {
		if {![catch {set a $repo_config(remote.$r.push)}]} {
			set enable 1
		}
	} else {
		catch {
			set fd [safe_open_file [gitdir remotes $r] r]
			while {[gets $fd n] >= 0} {
				if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
					set enable 1
					break
				}
			}
			close $fd
		}
	}

	if {$enable} {
		if {![winfo exists $push_m]} {
			menu $push_m
			$remote_m insert 0 cascade \
				-label [mc "Push to"] \
				-menu $push_m
		}

		$push_m add command \
			-label $r \
			-command [list push_to $r]
	}
}

proc make_sure_remote_submenues_exist {remote_m} {
	set fetch_m $remote_m.fetch
	set prune_m $remote_m.prune
	set remove_m $remote_m.remove

	if {![winfo exists $fetch_m]} {
		menu $remove_m
		$remote_m insert 0 cascade \
			-label [mc "Remove Remote"] \
			-menu $remove_m

		menu $prune_m
		$remote_m insert 0 cascade \
			-label [mc "Prune from"] \
			-menu $prune_m

		menu $fetch_m
		$remote_m insert 0 cascade \
			-label [mc "Fetch from"] \
			-menu $fetch_m
	}
}

proc update_all_remotes_menu_entry {} {
	global all_remotes

	set have_remote 0
	foreach r $all_remotes {
		incr have_remote
	}

	set remote_m .mbar.remote
	set fetch_m $remote_m.fetch
	set prune_m $remote_m.prune
	if {$have_remote > 1} {
		make_sure_remote_submenues_exist $remote_m
		if {[$fetch_m type end] eq "command" \
				&& [$fetch_m entrycget end -label] ne [mc "All"]} {

			$fetch_m insert end separator
			$fetch_m insert end command \
				-label [mc "All"] \
				-command fetch_from_all

			$prune_m insert end separator
			$prune_m insert end command \
				-label [mc "All"] \
				-command prune_from_all
		}
	} else {
		if {[winfo exists $fetch_m]} {
			if {[$fetch_m type end] eq "command" \
					&& [$fetch_m entrycget end -label] eq [mc "All"]} {

				delete_from_menu $fetch_m end
				delete_from_menu $fetch_m end

				delete_from_menu $prune_m end
				delete_from_menu $prune_m end
			}
		}
	}
}

proc populate_remotes_menu {} {
	global all_remotes

	foreach r $all_remotes {
		add_fetch_entry $r
		add_push_entry $r
	}

	update_all_remotes_menu_entry
}

proc add_single_remote {name location} {
	global all_remotes repo_config
	lappend all_remotes $name

	git remote add $name $location

	# XXX: Better re-read the config so that we will never get out
	# of sync with git remote implementation?
	set repo_config(remote.$name.url) $location
	set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*"

	add_fetch_entry $name
	add_push_entry $name

	update_all_remotes_menu_entry
}

proc delete_from_menu {menu name} {
	if {[winfo exists $menu]} {
		$menu delete $name
	}
}

proc remove_remote {name} {
	global all_remotes repo_config

	git remote rm $name

	catch {
		# Missing values are ok
		unset repo_config(remote.$name.url)
		unset repo_config(remote.$name.fetch)
		unset repo_config(remote.$name.push)
	}

	set i [lsearch -exact $all_remotes $name]
	set all_remotes [lreplace $all_remotes $i $i]

	set remote_m .mbar.remote
	delete_from_menu $remote_m.fetch $name
	delete_from_menu $remote_m.prune $name
	delete_from_menu $remote_m.remove $name
	# Not all remotes are in the push menu
	catch { delete_from_menu $remote_m.push $name }

	update_all_remotes_menu_entry
}
