#!/usr/bin/perl
#use Mooix::Thing;
use Mooix::CallStack;

my %indextoobj;
my %list;

sub under {
	my $h=shift;
	my $level=int(shift);
	return if $level > 4;
	
	# This could be done better, it doesn't really mimic ps -f yet.
	my $ret;
	$ret .= "   " x ($level - 1);
	$ret .= "\\_ " if $level;
	$ret .= "$indextoobj{$h->{index}}->$h->{method}";
	$ret .= " [x".@{$h->{uid}}."]" if @{$h->{uid}} > 1;
	$ret .= "\n";

	foreach my $i (values %list) {
		if ($i->{callindex} == $h->{index} &&
		    $i->{callmethod} eq $h->{method}) {
			$ret.=under($i, $level+1)
		}
	}

	return $ret;
}

run sub {
	my $this = shift;
	%_=@_;

	# Make sure that this command is not spoofed, just in case.
        if ($_{avatar} != $this) {
		fail "No!"; 
	}
	
	my $obj = $_{direct_object};
	my $session = $_{session};
	
	my @indexes;
	
	my $i = Mooix::CallStack::iterator;
	while (my $n = $i->next) {
		my $s = Mooix::CallStack::load(Mooix::CallStack::file($n));
		# Check $s because the stack could fail to load if the
		# process went away.
		if ($s && (! $obj || $s->index == $obj->index)) {
			my $c = $s->next;
			my $listindex=$s->index.$s->basemethod;
			unless (exists $list{$listindex}) {
				$list{$listindex} = {
					'index' => $s->index,
					'method' => $s->basemethod,
					'callindex' => $c ? $c->index : '',
					'callmethod' => $c ? $c->basemethod : '',
				};
			}
			push @{$list{$listindex}->{uid}}, $n;
			push @indexes, $s->index;
		}
	}

	if ($obj) {
		$indextoobj{$obj->index} = $obj;
	}
	else {
		foreach my $obj ($this->deindex(@indexes)) {
			$indextoobj{shift @indexes}=$obj;
		}
	}
	
	my $ret;
	if (%list) {
		# Printing out a tree structure, find topmost items in
		# tree and work down.
		foreach (values %list) {
			if (! exists $list{$_->{callindex}.$_->{callmethod}}) {
				$ret .= under($_);
			}
		}
	}
	else {
		$ret = "[inactive]";
	}
	$session->write($ret);
}
