#!/usr/bin/perl -T -w
#
# Zymonic Business Process and Information Management System
# Copyright Zednax Limited 2008 -
# For Authors and Changelog see the subversion history
use strict;

# Library path
BEGIN
{
    use vars qw($location $script_name $script_location $utils);
    use Zymonic::Utils qw(clean debug death_handler debug_exception rethrow_exception);
    $main::SIG{__DIE__} = \&death_handler;
}

# Config Vars
my $saxon = 0;

# XML out
my $xmlout = {};

# Global objects
my $config;
my $db;
my $auth;

# Modules
use Zymonic::Config;
use Zymonic::Session;
use Zymonic::DB;
use Zymonic::Auth;
use XML::Simple;

my $protocol = ( ( defined( $ENV{HTTPS} ) and $ENV{HTTPS} eq 'on' ) ? 'https' : 'http' );

# Clean path
$ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/sbin:/usr/sbin";

# set binmode for STDOUT and STDERR to handle unicode
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';

# Create a session (CGI only)
$ENV{SERVER_NAME} = clean( $ENV{SERVER_NAME}, "-_" );
our $session = Zymonic::Session->new(
    ip_address => clean( $ENV{REMOTE_ADDR} ),
    protocol   => $protocol
);

my $system = $session->system_name( $ENV{SERVER_NAME}, "/etc/zymonic" );

# Get any flags
my $no_display_attributes = $session->no_display_attributes;

debug("Zymonic starting... system: $system");

$config = Zymonic::Config->new(
    system_name => $system,
    config_dir  => "/etc/zymonic",
    ip_address  => clean( $ENV{REMOTE_ADDR} ),
    protocol    => $protocol,
);

my $redirect_url = '';

$db = Zymonic::DB->new( config => $config );
$session->{DB} = $db;

$auth = Zymonic::Auth->new(
    config      => $config,
    session     => $session,
    DB          => $db,
    user        => '',
    credentials => '',
    logged_in   => '',
    ip_address  => $session->{ip_address}
);

# Initialise the session fully
$session->initialise_session(
    {
        config => $config,
        auth   => $auth,
        DB     => $db
    }
);

# check if servside xslt is required
$saxon = $session->server_side_xslt();

# build documentation if needed
if ( $session->build_documentation )
{
    eval {
        $config->build_documentation($auth);
        1;
      } or do
    {

        # don't let any exceptions here bring the system down
        # debug it but ignore it
        my $exception = $@;
        if ($exception)
        {
            if ( ref($exception) and $exception->isa('Zymonic::Exception') )
            {
                debug_exception($exception);
            }
            else
            {
                debug( 'Unknown Exception (or a die): ' . Dumper($exception) );
            }
        }
    };
}

eval {
    $xmlout = $session->view_control($no_display_attributes);
    1;
  }
  or do
{
    my $exception = $@;
    if ( $exception and ref($exception) and $exception->isa('Zymonic::Exception::State::Redirect') )
    {
        $redirect_url = $exception->redirect_url;
    }
    else
    {
        rethrow_exception($exception);
    }
};

unless ( $no_display_attributes or ( defined( $xmlout->{css} ) and $xmlout->{css} ) )

{
    $xmlout->{css} = "/ZymonicDefault.css";
}

# check for custom xsl
my $xsl = $session->clean_param( 'ZZxsl', '/\\-._' );
my $xsl_with_path = $config->{htmlroot};
unless ($xsl)
{
    if ( ref( $xmlout->{currentpage} ) && $xmlout->{currentpage}->{xsl} )
    {
        $xsl = $xmlout->{currentpage}->{xsl};
    }
    else
    {
        $xsl = $config->{xslt};
    }
}

# Output the XML
if ($redirect_url)
{
    print $session->redirect($redirect_url);
}
elsif ( $session->clean_param("notransform") or $no_display_attributes )
{
    print $session->header;
    print XMLout(
        $xmlout,
        KeyAttr       => [],
        RootName      => "Zymonic",
        NoEscape      => 1,
        SuppressEmpty => 1
    );
}
else
{
    if ( !$saxon )
    {

        print $session->header;
        print "<?xml-stylesheet href=\"" . $xsl . "\" type=\"text/xsl\"?>\n";

        print XMLout(
            $xmlout,
            KeyAttr       => [],
            RootName      => "Zymonic",
            NoEscape      => 1,
            SuppressEmpty => 1
        );
    }
    else
    {
        open( XT, ">/tmp/xml.$$" );
        print XT XMLout(
            $xmlout,
            KeyAttr       => [],
            RootName      => "Zymonic",
            NoEscape      => 1,
            SuppressEmpty => 1
        );
        close(XT);

        debug("Server Side XSLT: /usr/local/bin/saxon /tmp/xml.$$ $xsl_with_path/$xsl");
        print $session->header( type => 'text/html' );
        print `/usr/local/bin/saxon /tmp/xml.$$ $xsl_with_path/$xsl`;
    }
}
