#!/usr/bin/perl 
#
###########################################################################
# <LICENSEINFO>
# Copyright (C) Daniel Guermeur - 1999-2001
# Copyright (C) Metadot Corporation - 2001-2004
# 
# This file is part of Metadot Portal Server software $Name: Release_6_4b2 $
# 
# Metadot Portal Server software is free software; you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
# 
# Metadot Portal Server software is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with
# Metadot Portal Server; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
# For more information, please contact info@metadot.com.
#</LICENSEINFO>
#
#
#
############################################################################

my $DEBUG = 0;

use Time::HiRes qw(gettimeofday);
my $start_time = [gettimeofday];
use strict;

use Metadot qw($USER %FORM $SESSION $HTTP_HEADER_SENT $PARAMS $DISPLAY $CGI %REQUEST_VARS);
use Metadot::UserFactory;
use Portal;
use Template;
use Utility;
use Metadot::PortalFactory;
use Metadot::RequestContext;
use Metadot::SystemApp::EventLog;

# causes Metadot to discover and register all Gizmo3000
use Metadot::Gizmo3000::ClassRegistry;

use CGI qw(:standard :html3);
use CGI::Cookie;

use CGI::Carp qw(fatalsToBrowser); # use this for debugging purposes
#use CGI::Carp qw();  #secu_200401: suppress revealing too much information to the browser

#################################################
# Create a Metadot portal instance
#################################################
my $Mdot = Portal->new(1);

$Mdot->debug_msg(4, "index.pl: \@INC contains " . join(", ", @INC));    

### start timer
if ($SESSION) {
   $SESSION->set_start_timer($start_time);
}

### CHECK TO SEE IF SITE SUSPENDED - FOR SHAREM
my $suspended_mode = $PARAMS->{is_suspended};
unless (defined($suspended_mode)) {
    $suspended_mode = $PARAMS->{is_suspended} = MetadotConfig->get_site_is_suspended();
}
if (($suspended_mode) eq 'true') {
    $Mdot->md_redirect('/suspended.html');
}


# we have to determine $iid
my $iid ;
if (defined $FORM{id}) { $iid = $FORM{id}; }
elsif (defined $FORM{iid})  { $iid = $FORM{iid}; }
elsif ($CGI->path_info =~ m!\A/users{0,1}\/(.*)!) {
    $FORM{isa} = 'User';
    $FORM{op} = 'show_users_portal';
    $FORM{user} = $1; }
elsif ($CGI->path_info =~ m!\A/(.*)!) {
    require Metadot::Utils::Search;
    Metadot::Utils::Search->show_project_portal($1);
    exit_script(0);    
    
 }

# if no values are sent at all, send to the home page.
elsif (!defined $FORM{isa}) {
    # redirect to home page if defined, and this script is not the home page
    if (($PARAMS->{home_page}) && !($0 =~ m/$PARAMS->{home_page}$/)) {
        $Mdot->md_redirect($PARAMS->{home_page});
    } else {
        $iid = 0;
    }
} 

$iid = undef unless Utility->is_valid_integer($iid); # secu_200401
$FORM{iid} = $FORM{id} = $iid;

# we have to determine $isa
my $isa ;
if (defined $FORM{isa}) { 
    $isa = $FORM{isa} ;
} elsif (defined $iid) { 
    eval {
        ($isa) = DBAccess->sqlSelect("isa", "instance", "iid=$iid") ; 
    };
    if ($@) {
        ErrorHandling->printError("Error performing query: $@");
        return;
    }
} 

$FORM{isa} = $isa = $isa || 'Category';

# we have to determine $op
my $op;
if (defined $FORM{op}) {

    $op = $FORM{op} ; 

} else { 

    $op = "show";    # by default we try to display the object
} 

# handle old operator
if (lc($op) eq "showusers"){ $op = "show_users" ; $isa = "Portal" ;}
if (lc($op) eq "myportal") { $op = "myportal"  ; $isa = "Portal" ; }

$FORM{op} = $op = lc($op) ;

# display debug information
$Mdot->debug_msg(4, "index.pl: iid=" . ($iid||"") . " isa=$isa op=$op");

 # Log the post information to the event log
 if ($PARAMS->{is_event_log_enabled}) {
         Metadot::SystemApp::EventLog->log_event({
#  					 user_id => $USER->uid,
 					 userid => $USER->uid,
 					 user_name => $USER->fullname,
 					 sub_application_name => 'index.pl',
 					 class_name => $isa,
 					 operation_name => $op,
 					 instance_id => $iid,
 					},
 					\%FORM
 				       );
 }


### MAIN OPERATOR SWITCH ###

my $app = undef;
if (defined($FORM{app})) { $app = $FORM{app}; }


debug_msg("server: ".MetadotConfig->get_server_name()."; isa=$isa; iid=$iid; op=$op;");


#instanciate right object
my $gizmo_object;
my $object;
if ($isa eq 'Channel') { require "Channel.pm"; $object = Channel->new($FORM{cid}); }
elsif ($isa eq 'Message') { require "Message.pm"; $object = Message->new($FORM{mid}); }
elsif ($isa eq 'Portal')  { $object = $Mdot; }
elsif ($isa eq 'Session') { $object = $SESSION; }
elsif ($isa eq 'User')    { $object = Metadot::UserFactory->get_user( $SESSION->uid() ); }
elsif ($isa =~ /^Metadot::User::/) { $object = Metadot::UserFactory->get_user( $FORM{id} ); }
elsif ($isa eq 'Group')   { require "Group.pm"; $object = Group->new($FORM{grp_id});}
elsif ($isa eq 'Project') { require "Gizmo.pm"; require "Gizmo/Project.pm"; $object = $isa->new($iid);}
elsif ($isa eq 'Register'){ require "Metadot/RegisterFactory.pm"; $object = Metadot::RegisterFactory->get_register();}
elsif ($isa eq 'Status')  { require "Metadot/Status.pm"; $object = Metadot::Status->new();}
elsif ($isa eq 'SuperGizmo' && !defined($iid))  { require "Gizmo/$isa.pm"; $object = $isa->new();}
elsif ( $isa =~ /^Metadot::SystemApp:/ ) {
    
    eval { $object = $isa->new($iid); };
    
    if( $@ ) {
	
	require "Metadot/SystemApp.pm";    
	(my $path = $isa) =~ s/::/\//g;
	eval { require "$path.pm" };

	if($@) {
	    $Mdot->print_click_back("SystemApp $isa is not installed, please contact your site administrator for help");
	    exit_script(0);
	}
	
	$object = $isa->new($iid); 
    }
    
} elsif ($app) { 

    require "Gizmo.pm";
    my $file = undef;
    $app = $Mdot->require_app($app);
    if ($isa eq "Category"){
	require "App/$app/$app.pm";
	$file = "App::".$app."::".$app;
	$object = $file->new($iid);
    } else {
	require "App/$app/$app.pm";
	$file = "App::".$app."::".$app;
	$gizmo_object = $isa->new($iid);
	my $pid = $gizmo_object->parent_id();
	$object = $file->new($pid);
    }
} else { 

    require "Gizmo.pm"; 
    require "GizmoTool.pm"; 
    $Mdot->debug_msg(4,"index.pl restoring the gizmo using isa='$isa', iid='$iid'");
    #debug_msg("index.pl restoring the gizmo using isa='$isa', iid='$iid'");
    eval {
        # Some gizmos, like Table sometimes call themselves back w/o passing ISA
        if ($isa->isa('Metadot::GizmoSingleton')) {
            $object = $isa->get_instance();
        } else {
            $object = $isa->restore($iid);            
        }
        
        # sometimes the isa was wrong; this ensures it is correct
        if (defined($object)) {
            $FORM{isa} = $isa = $object->get_is_a();
        }

        $Mdot->debug_msg(4,"index.pl restored the gizmo $object; form{isa}=$FORM{isa}; isa=$isa");
        #debug_msg("index.pl restored the gizmo $object; form{isa}=$FORM{isa}; isa=$isa");
    };
   if ($@ || !defined($object)) {
       $DISPLAY->print_click_back("Looking for something?","Sorry, the web address you entered is not a functioning page on our site. Please double-check the URL for typos and other errors, or go to the home page.");  # secu_200401
       if ($@) {
           debug_msg("Error: $@");
           ErrorHandling->printError("Error: $@");
       }
       exit_script();
   }
}

# try to get a response from the MetadotController object. Note, MetadotController
# is responsible for its own access control.
if ($PARAMS->{use_controller}) {
    my $controller = Metadot::PortalFactory->get_controller();
    my $context = Metadot::PortalFactory->build_context({
        subject         => $object,
        op              => $op,
        user            => $USER,
        form            => \%FORM,
        session         => $SESSION,
        request_vars    => \%REQUEST_VARS,
    });
    my $response = $controller->do($context);
    if ($response) {
        my $timer_count = $SESSION->timer_count();
        $DISPLAY->print_http_header();
        print $DISPLAY->print_comment_tag();
        print $response;
        print $SESSION->get_timer_count_html($timer_count);
        exit_script();
    }    
}


# enforce AC

#RESTRICTED-USER
my $restricted_home = 'restricted_user_home';
if ($USER->is_restricted()) {
    my $url = $DISPLAY->make_url("index.pl?isa=User&amp;op=$restricted_home");
    if ($gizmo_object){
        unless($gizmo_object->is_allowed_to_do($op, $USER, 1)) {
        Utility->md_redirect($url);
        }
    } else {
        unless($object->is_allowed_to_do($op, $USER, 1)) {
        Utility->md_redirect($url);
        }     
    }
}

if ($gizmo_object){
    unless($gizmo_object->is_allowed_to_do($op, $USER, 1)) {
	$DISPLAY->print_click_back( "Operation is not allowed", "<br>Sorry, you are not allowed to perform this action."); 
	exit_script(0);      
    }
} elsif ($object) {
    unless($object->is_allowed_to_do($op, $USER, 1)) {
	$DISPLAY->print_click_back( "Operation is not allowed", "<br>Sorry, you are not allowed to perform this action."); 
#  	$object->print_click_back( "Error", "index.pl:<br>Sorry, you are not allowed to do operation:<br> -$op-<br>$0");	
	exit_script(0); 
    }     
}

# order the object to handle the operation
if ($object) {      # secu_200401
    if ($app && $gizmo_object) {
        $object->display_controller($op, $gizmo_object);
    } else {
        $Mdot->debug_msg(4, "index.pl: Handling $op using $object");    
        debug_msg("index.pl: Handling $op using $object");    
        $object->handle($op);
    }
}

exit_script();







sub exit_script {
    my @args = @_;
    
    debug_msg("index.pl terminated successfully");

    exit(@args);
}

sub debug_msg {
    my @args = @_;
    if ($DEBUG) {
        print STDERR "[DEBUG $Mdot ".localtime(time)."]  ", @args, "\n";
    }
}
