#!/usr/local/bin/perl -w 

# Copyright (C) 2002 Michael Gage 

###############################################################################
# Web service which fetches WeBWorK problems from a library.
###############################################################################


#use lib '/home/gage/webwork/pg/lib';
#use lib '/home/gage/webwork/webwork-modperl/lib';

package WebworkWebservice::LibraryActions;
use WebworkWebservice;
use base qw(WebworkWebservice); 

use strict;
use sigtrap;
use Carp;
use Safe;
use Apache;
use WeBWorK::Utils;
use WeBWorK::CourseEnvironment;
use WeBWorK::PG::Translator;
use WeBWorK::PG::IO;
use Benchmark;
use MIME::Base64 qw( encode_base64 decode_base64);

##############################################
#   Obtain basic information about directories, course name and host 
##############################################
our $WW_DIRECTORY = $WebworkWebservice::WW_DIRECTORY;
our $PG_DIRECTORY = $WebworkWebservice::PG_DIRECTORY;
our $COURSENAME   = $WebworkWebservice::COURSENAME;
our $HOST_NAME    = $WebworkWebservice::HOST_NAME;
our $PASSWORD     = $WebworkWebservice::PASSWORD;
our $ce           = WeBWorK::CourseEnvironment->new($WW_DIRECTORY, "", "", $COURSENAME);
#warn "library ce \n ", WebworkWebservice::pretty_print_rh($ce);
warn "LibraryActions is ready";

##############################################
#   Obtain basic information about local libraries
##############################################
 my %prob_libs	= %{$ce->{courseFiles}->{problibs} };

 warn pretty_print_rh(\%prob_libs);
 # replace library names with full paths
 
 my $templateDir    = $ce->{courseDirs}->{templates};
# warn "template Directory is $templateDir";
 foreach my $key (keys %prob_libs) {
 	$prob_libs{$key} = "$templateDir/$key";
 }
 #warn "prob libraries", WebworkWebservice::pretty_print_rh(\%prob_libs);

sub listLibraries {
	my $rh = shift;
	return [sort keys %prob_libs];
}

use File::stat;
sub readFile {
	my $rh = shift;
	local($|)=1;
	my $out = {};
	my $filePath = $rh->{filePath};
	unless ($rh->{pw} eq $PASSWORD ) {
		$out->{error} =404;
		return($out);
	}
	if (  defined($prob_libs{$rh->{library_name}} )   ) {
		$filePath = $prob_libs{$rh->{library_name}} .'/'. $filePath;
	} else {
		$out->{error} = "Could not find library:".$rh->{library_name}.":";
		return($out);
	}
	
	if (-r $filePath) {
		open IN, "<$filePath";
		local($/)=undef;
		my $text = <IN>;
		$out->{text}= encode_base64($text);
		my $sb=stat($filePath);
		$out->{size}=$sb->size;
		$out->{path}=$filePath;
		$out->{permissions}=$sb->mode&07777;
		$out->{modTime}=scalar localtime $sb->mtime;
		close(IN);
	} else {
		$out->{error} = "Could not read file at |$filePath|";
	}
	return($out);
}



use File::Find;	
sub listLib {
	my $rh = shift;
	my $out = {};
	my $dirPath;
	unless ($rh->{pw} eq $PASSWORD ) {
		$out->{error}=" 404 $PASSWORD and ".$rh->{pw};
		return($out);
	}
	
	if (  defined($prob_libs{$rh->{library_name}} )   ) {
		$dirPath = $prob_libs{$rh->{library_name}} ;
	} else {
		$out->{error} = "Could not find library:".$rh->{library_name}.":";
		return($out);
	}
    warn "library directory path is $dirPath";
	my @outListLib;
	my $wanted = sub {
		my $name = $File::Find::name;
		my @out=();
		if ($name =~/\S/ ) {
			$name =~ s|^$dirPath/*||o;  # cut the first directory
            # $name =~ s|^\w*\/||;     # cut the set name
			push(@outListLib, "$name") if $name =~/\.pg/;

		}
	};
	 
	my $command = $rh->{command};
	$command = 'all' unless defined($command);
			$command eq 'all' &&    do {print "$dirPath\n\n";
										find($wanted, $dirPath);
										@outListLib = sort @outListLib;
										$out->{ra_out} = \@outListLib;
										$out->{text} = join("\n", @outListLib);
										return($out);
			};
			$command eq 'setsOnly' &&   do {
											if ( opendir(DIR, $dirPath) ) {  
											    my @fileList=();
												while (defined(my $file = readdir(DIR))) {
													push(@fileList,$file) if -d "$dirPath/$file";
													
												}
												$out->{text} = join("\n",sort @fileList);
												closedir(DIR);
											} else {
												$out->{error}= "Can't open directory $dirPath";
											}
											return($out);
			};

			$command eq 'listSet' && do {@outListLib=();
			 							 my $dirPath2 = $dirPath . $rh->{set};
			 							 
			 							 if ( -e $dirPath2) {
											 find($wanted, $dirPath2);
											 $out ->{text} = join("\n", sort @outListLib );
										 } else {
										   $out->{error} = "Can't open directory $dirPath2";
										 }
										 return($out);

			};
			# else
			$out->{error}="Unrecognized command $command";
			$out;
}


sub pretty_print_rh {
	my $rh = shift;
	my $out = "";
	my $type = ref($rh);
	if ( ref($rh) =~/HASH/ ) {
 		foreach my $key (sort keys %{$rh})  {
 			$out .= "  $key => " . pretty_print_rh( $rh->{$key} ) . "\n";
 		}
	} elsif ( ref($rh) =~ /SCALAR/ ) {
		$out = "scalar reference ". ${$rh};
	} elsif ( ref($rh) =~/Base64/ ) {
		$out .= "base64 reference " .$$rh;
	} else {
		$out =  $rh;
	}
	if (defined($type) ) {
		$out .= "type = $type \n";
	}
	return $out;
}


1;
