package rbCGI;


use strict; 
no strict 'subs';
no strict 'refs'; # allow filehandles to be variables and viceversa

use CGI;
use Cwd;
use MIME::Base64;

@rbCGI::ISA = ( 'CGI' ); 

sub new {
    my $class = shift @_;
    
    my $self = new CGI;

    $self->{'site_filename'} = "rbsite.cfg";
    
    return bless $self, $class;
}


sub parse_cgi_args
{
    my $self = shift @_;
    my $xml = (defined $self->param("xml")) ? 1 : 0;

    $self->{'xml'} = $xml;

    my @var_names = $self->param;
    my @arg_list = ();
    foreach my $n ( @var_names ) {
	my $arg = "$n=";
	my $val =  $self->param($n);
	$arg .= $val if (defined $val);
	push(@arg_list,$arg);
    }
	
    $self->{'args'} = join("&",@arg_list);
}


sub clean_param
{
    my $self = shift @_;
    my ($param) = @_;

    my $val = $self->SUPER::param($param);
    $val =~ s/[\r\n]+$// if (defined $val);

    return $val;
}

sub safe_val
{
    my $self = shift @_;
    my ($val) = @_;

    # ensure only alpha-numeric plus a few other special chars remain

    $val =~ s/[^[:alnum:]@\.\/\- :_]//g if (defined $val); 

    return $val;
}

sub generate_message
{
    my $self = shift @_;
    my ($message) = @_;
    
    print STDOUT "Content-type:text/plain\n\n$message";

}

sub generate_error
{
    my $self = shift @_;
    my ($mess) = @_;
    
    my $xml = $self->{'xml'};

    my $full_mess;
    my $args = $self->{'args'};

    if ($xml) {
	# Make $args XML safe
	my $args_xml_safe = $args;
	$args_xml_safe =~ s/&/&amp;/g;

	$full_mess =  "<Error>\n";
	$full_mess .= "  $mess\n";
	$full_mess .= "  CGI args were: $args_xml_safe\n";
	$full_mess .= "</Error>\n";
    }
    else {
	$full_mess = "ERROR: $mess\n  ($args)\n";
    }

    $self->generate_message($full_mess);

    die $full_mess;
}

sub generate_warning
{
    my $self = shift @_;
    my ($mess) = @_;
    
    my $xml = $self->{'xml'};

    my $full_mess;
    my $args = $self->{'args'};

    if ($xml) {
	# Make $args XML safe
	my $args_xml_safe = $args;
	$args_xml_safe =~ s/&/&amp;/g;

	$full_mess =  "<Warning>\n";
	$full_mess .= "  $mess\n";
	$full_mess .= "  CGI args were: $args_xml_safe\n";
	$full_mess .= "</Warning>\n";
    }
    else {
	$full_mess = "Warning: $mess ($args)\n";
    }

    $self->generate_message($full_mess);

    print STDERR $full_mess;
}


sub generate_ok_message
{
    my $self = shift @_;
    my ($mess) = @_;
    
    my $xml = $self->{'xml'};

    my $full_mess;

    if ($xml) {
	$full_mess =  "<Accepted>\n";
	$full_mess .= "  $mess\n";
	$full_mess .= "</Accepted>\n";
    }
    else {
	$full_mess = "$mess\n";
    }
 
    $self->generate_message($full_mess);
}



sub get_config_info {
    my $self = shift @_;
    my ($infotype, $optional) = @_;

    my $site_filename = $self->{'site_filename'};
    open (FILEIN, "<$site_filename") 
	|| $self->generate_error("Could not open $site_filename");

    my $config_content = "";
    while(defined (my $line = <FILEIN>)) {
	$config_content .= $line;
    }
    close(FILEIN);

    my ($loc) = ($config_content =~ m/^$infotype\s+((\".+\")|(\S+))\s*\n/m);
    $loc =~ s/\"//g if defined $loc;

    if ((!defined $loc) || ($loc =~ m/^\s*$/)) {
	if((!defined $optional) || (!$optional)) {
	    $self->generate_error("$infotype is not set in $site_filename");
	}
    }

    return $loc;
}


sub get_rb_home {
    my $self = shift @_;
    
    if (defined $self->{'rbhome'}) {
	return $self->{'rbhome'};
    }

    my $rbhome = $self->get_config_info("rbhome");

    $rbhome =~ s/(\/|\\)$//; # remove trailing slash

    $self->{'rbhome'} = $rbhome;

    return $rbhome;
}

sub get_rb_os {
    my $self = shift @_;
    
    my $os = $^O;

    if ($os =~ m/linux/i) {
	return "linux";
    }
    elsif ($os =~ m/mswin/i) {
	return "windows";
    }
    elsif ($os =~ m/macos/i) {
	return "darwin";
    }
    else {
	# return as is.
	return $os;
    }
}


sub setup_rb {
    my $self = shift @_;
    my $optional = 1; # ignore absence of specified properties in rbsite.cfg if not found

    my $rbhome = $self->get_rb_home();
    my $rbos = $self->get_rb_os();
    $ENV{'REALISTIC_BOOKS_HOME'} = $rbhome;
    $ENV{'RBOS'} = $rbos;
    $ENV{'GSDLOS'} = $rbos;

    require util;

    my $rb_bin_script = &util::filename_cat($rbhome,"bin","script");
    &util::envvar_append("PATH",$rb_bin_script);
    
    my $rb_bin_os = &util::filename_cat($rbhome,"bin",$rbos);
    &util::envvar_append("PATH",$rb_bin_os);


    my $rb_bin_perl = &util::filename_cat($rbhome,"bin",$rbos,"perl","bin");
    &util::envvar_append("PATH",$rb_bin_perl);
    
}


sub checked_chdir
{
    my $self = shift @_;
    my ($dir) = @_;

    if (!-e $dir) {
	$self->generate_error("Directory '$dir' does not exist");
    }

    chdir $dir
	|| $self->generate_error("Unable to change to directory: $dir");
}


sub decode {
    my ($self, $text) = @_;
    $text =~ s/\+/ /g;
    $text = &MIME::Base64::decode_base64($text);

    return $text;
}

1;

