use File::Basename;


#envi messages
sub envi_message {
	my($message) = @_;
	if ( $envi_verbose ) {
		print "envi message: $message\n";
	}
}

#TASK FUNCTIONS
sub task_location {

	if ( !exists $_[0] ) { return ""; }

	local $task = $_[0];

	local @locations = ( "$ENV{'HOME'}/.envi/tasks", "$ENV{'ENVI_HOME'}/etc/tasks" );
	foreach (@locations) {
		#try for basic task with one name
		if ( -f "$_/$task/task.pl" ) {
			return "$_/$task";
		#try for link to another task
		} elsif ( -f "$_/$task" ) {
			open (TASKFILE, "$_/$task");
			$line = <TASKFILE>;
			chomp $line;
			close (TASKFILE);
			if ( $line =~ "alias-for:(.*)" ) {
				return task_location($1);
			}
		#try for a built-in official task alias
		} else {
			@taskdirs = glob "$_/*";
			foreach $dir ( @taskdirs ) {
				if ( -f "$dir/aliases.txt" ) {
					open (ALIASES, "$dir/aliases.txt");
					while ( $line = <ALIASES> ) {
						chomp $line;
						if ( $line eq $task ) {
							my $resolved = basename($dir);
							return task_location($resolved);
						}
					}
				}
			}
		}
		
	}

}

sub task_exists {
	if ( ! exists $_[0] || !task_location($_[0]) ) {
		return 0;
	}
	return 1;
}

sub task_canonical_name {
	if ( ! exists $_[0] || !task_location($_[0]) ) {
		return;
	}
	return basename(task_location($_[0]));
}

sub run_task {
	if ( ! exists $_[0] || !task_exists($_[0])) {
		return;
	}
	envi_message( "in run task $_[0]");
	local $task = $_[0];

	#let rt.pl take over from here, so a new environment context created for the
	#run of the task, which will be destroyed when rt.pl exits
	local $command = "perl \"$ENV{'ENVI_HOME'}/lib/rt.pl\" \"$task\"";
	for my $a ( @ARGV ) {
		$command .= " \"$a\"";
	}

	envi_message( "About to run rt.pl command: $command" );
	system( $command );

}

sub user_task_environment_script {
	if ( ! exists $_[0] || !task_location($_[0]) ) { return ""; }
	return "$ENV{'HOME'}/.envi/tasks/" . task_canonical_name($_[0]) . "/environment.pl";
}

sub system_task_environment_script {
	if ( ! exists $_[0] || !task_location($_[0]) ) { return ""; }
	return "$ENV{'ENVI_HOME'}/etc/tasks/" . task_canonical_name($_[0]) . "/environment.pl";
}

sub list_tasks() {
	
	find_tasks( "$ENV{'HOME'}/.envi/tasks/*" );
	find_tasks( "$ENV{'ENVI_HOME'}/etc/tasks/*" );
}


#PLAYLIST FUNCTIONS
sub playlist_location {

	if ( !exists $_[0] ) { return ""; }

	local $playlist = $_[0];
	local $v = "";

	if ( -f ($v = "$ENV{'HOME'}/.envi/playlists/$playlist") ) {
		return $v;
	}

	if ( -f ($v = "$ENV{'ENVI_HOME'}/etc/playlists/$playlist") ) {
		return $v;
	}

	return "";
}

sub playlist_exists {
	if ( ! exists $_[0] || !playlist_location($_[0]) ) {
		return 0;
	}
	return 1;
}

sub run_playlist {
	if ( ! exists $_[0] || !playlist_exists($_[0])) {
		return;
	}

	local $playlist = $_[0];
	local $playlist_loc = playlist_location($playlist);

	#parse arguments
	local $ls=0;
	for my $arg ( @ARGV ) {
		#list tasks
		if ( $arg =~ "ls|tasks" ) {
			$ls=1;
		} else {
			die "Invalid argument: $arg\n";
		}
		shift(@ARGV);
	}

	local $task_cmd = "";
	open( FILE, "< $playlist_loc" ) or die "can't open $playlist_loc : $!";
	while( $task_cmd = <FILE> ) {
		chomp($task_cmd);
		if ( $task_cmd ne "" && substr($task_cmd,0,1) ne "#" ) {
			#show the task command
			if ( $ls ) {
				print "$task_cmd\n";
				#run the task
	        	} else {
				envi_message("Running '$task_cmd'");
				system( "$ENV{'ENVI_HOME'}/bin/envi.pl $task_cmd" );
			}
		}
	}
}

sub list_playlists {
	local_names( "$ENV{'HOME'}/.envi/playlists/*" );
	local_names( "$ENV{'ENVI_HOME'}/etc/playlists/*" );
}

sub local_names {
	if ( ! exists $_[0] ) { return; }
	@files = <$_[0]>;
	foreach $file (@files) {
		print basename($file) . "\n";
	}
}

sub find_tasks {
	if ( ! exists $_[0] ) { return; }
	@dirs = <$_[0]>;
	foreach $dir (@dirs) {
		#try task with aliases
		if ( -f "$dir/aliases.txt" ) {
			open (ALIASES, "$dir/aliases.txt");
			while ( $line = <ALIASES> ) {
				chomp $line;
				print "$line\n";
			}
		#task without aliases
		} else {
			print basename($dir) . "\n";
		}
	}
}

# first arg is 'bat' or 'bash'
# second arg is full path to script
# third arg, optional, is 1 if the script needs to be run from its containing
#  directory
sub source_script {
	#TODO: allow multiline environment variables
	if ( ! exists $_[0] || ! exists $_[1] ) { return; }
	if ( ! -f "$_[1]" ) { return; }
	my $in_place = 0;
	if (exists $_[2] && $_[2] == "1") {
	    $in_place = 1;
	}

	my $full_filename = $_[1];
	my $dirname = "";
	my $filename = $full_filename;
	if ($in_place == 1) {
	    $dirname = dirname($full_filename);
	    $filename = basename($full_filename);
	}
	my $rnd = rand();
	my $cmd = undef;
	if ( $^O eq "MSWin32" ) {
	    my $subcommand = '"' . $ENV{'ENVI_HOME'} . '\\lib\\source.' . $_[0] . '" "' . $filename . '" "' . $rnd . '"';
	    if ($in_place) {
		$subcommand .= ' "'.$dirname.'"';
	    }
		if ( $ENV{'ENVI_HOME'} =~ " " || $_[1] =~ " " ) {
			$cmd = 'cmd.exe /v:on /c ' . $subcommand;
		} else {
			$cmd = 'cmd.exe /v:on /c "' . $subcommand . '"';
		}
	} else {
	    $cmd = '"' . $ENV{'ENVI_HOME'} . '/lib/source.' . $_[0] . '" "' . $filename . '" "' . $rnd . '"';
	    if ($in_place) {
		$cmd .= ' "'.$dirname.'"';
	    }
	}

	open(SRC, "$cmd|") or die("Couldn't run command $cmd: $!\n");
	my $reading = 0;
	while ( my $line=<SRC> ) {
		chomp($line);
		if ( $reading ) {
			my ($name, $value) = split(/=/,$line,2);
			if ( $name !~ /^\_/ ) {
			    $ENV{$name} = $value;
			}
		} elsif ( $line eq "-- ENVIRONMENT \"$rnd\" --" ) {
			$reading = 1;
		} 
	}
	close(SRC);
}

sub source_bash_script {
	if ( ! -e $_[0] ) { print "Script $_[0] not found\n"; exit; }
	source_script("bash","$_[0]");
}
sub source_bash_script_in_place {
	if ( ! -e $_[0] ) { print "Script $_[0] not found\n"; exit; }
	source_script("bash","$_[0]", 1);
}

sub source_batch_script {
	if ( ! -e $_[0] ) { print "Script $_[0] not found\n";  exit; }
	source_script("bat","$_[0]");
}

sub source_batch_script_in_place {
    if ( ! -e $_[0] ) { print "Script $_[0] not found\n";  exit; }
    
	source_script("bat","$_[0]", 1);
}
    
}

