#!/usr/bin/perl -w
#
# Regina - A Normal Surface Theory Calculator
# Python Startup Script
#
# Copyright (c) 2002-2004, Ben Burton
# For further details contact Ben Burton (bab@debian.org).
#
# This script simply starts the Python interpreter and imports the Regina
# calculation engine, i.e., the module 'regina'.
#
# DO NOT EDIT THIS FILE DIRECTLY.  It has been automatically generated
# by configure and any changes will be overwritten.  Try editing
# regina-python.in instead.
#
# This program 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.
#
# This program 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 this program; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.

use strict;
use File::Basename;

# --- Constants. ---

# The program name.
my $prog_name = $0;

# Address to which questions should be emailed.
my $regina_support = "regina-user\@lists.sourceforge.net";

# Default verbosity level.
my $default_verbosity = 1;

# Local configuration files.
my $home = $ENV{HOME};
if (! $home) {
    $home = `echo ~`;
}
my $python_conf = $home . "/.regina-python";
my $libs_conf = $home . "/.regina-libs";

# --- Variables. ---

my $quiet = 0;
my $verbose = 0;
my $regina_home = '';
my $from_source = 0;
my $python_lib_dir = '';
my $python_cmd = '';
my @python_libs;
my $script = '';
my @script_args;

# --- Extract variables from the configuration file.

if (open(CONF, $python_conf)) {
    my @lines = <CONF>;
    chomp @lines;
    close(CONF);

    foreach my $line (@lines) {
        if ($line =~ /^\s*$/ or $line =~ /^\s*#/) {
            next;
        }
        if ($line =~ /^\s*([A-Za-z_]+)\s*=\s*$/) {
            &warn("W: Variable $1 is not assigned a value in $python_conf.\n");
            next;
        }
        if ($line =~ /^\s*([A-Za-z_]+)\s*=\s*(\S(.*\S)?)\s*$/) {
            # We have a configuration variable.
            if ($1 eq 'REGINA_VERBOSITY') {
                &setVerbosity($2);
            } elsif ($1 eq 'REGINA_PYTHON') {
                &setPythonCmd($2);
            } elsif ($1 eq 'REGINA_PYLIBDIR') {
                &setPythonLibDir($2);
            } elsif ($1 eq 'REGINA_HOME') {
                &setReginaHome($2);
            } else {
                &warn("W: Unknown variable $1 in $python_conf.\n");
            }
            next;
        }
        &warn("W: Bad line in $python_conf:\n$line\n");
    }
}

# --- Extract variables from the environment. ---

if ($ENV{REGINA_VERBOSITY}) {
    &setVerbosity($ENV{REGINA_VERBOSITY});
}
if ($ENV{REGINA_HOME}) {
    &setReginaHome($ENV{REGINA_HOME});
}
if ($ENV{REGINA_PYTHON}) {
    &setPythonCmd($ENV{REGINA_PYTHON});
}
if ($ENV{REGINA_PYLIBDIR}) {
    &setPythonLibDir($ENV{REGINA_PYLIBDIR});
}

# --- Parse the command-line options. ---

my $readingScriptArgs = 0;
foreach my $arg (@ARGV) {
    if ($readingScriptArgs) {
        push @script_args, $arg;
        next;
    }

    if ($arg eq '-q' or $arg eq '--quiet') {
        $quiet = 1;
        $verbose = 0;
        next;
    }

    if ($arg eq '-v' or $arg eq '--verbose') {
        $quiet = 0;
        $verbose = 1;
        next;
    }

    if ($arg =~ /^-/) {
        &err("Unrecognised option: $arg\n");
        &usage;
    }

    # We must be onto the script.
    $script = $arg;
    $readingScriptArgs = 1;
}

# --- Check that the current options are reasonable. ---

my $prefix = "/usr";
my $exec_prefix = "${prefix}";
my $datadir = "${prefix}/share";
my $libdir = "/usr/lib";
my $package = "regina-normal";

if (! $regina_home) {
    if ( -e "$prog_name.in" and -f dirname($prog_name) . '/../admin/ac_gen') {
        &info("I: Running from the source tree.\n");
        $from_source = 1;
        &setReginaHome(dirname($prog_name) . '/..');
    } else {
        &info("I: Running from an installation.\n");
        &setReginaHome("$datadir/$package");
    }
}

if (! $python_cmd) {
    my $which_python;
    chomp($which_python = `which python2.3`);
    if (! $which_python) {
        &err("E: A Python interpreter could not be found.\n");
        &err("E: Set \$REGINA_PYTHON to a Python interpreter (such as /usr/bin/python)\n");
        &err("E: and try again.\n");
        exit 1;
    }
    &setPythonCmd($which_python);
}

if (! $python_lib_dir) {
    &setPythonLibDir($from_source ? "$regina_home/python/.libs" :
        "$libdir/$package/python");
}

# --- Read the list of libraries to load. ---

if (open(LIBS, $libs_conf)) {
    my @lines = <LIBS>;
    chomp @lines;
    close(LIBS);

    foreach my $line (@lines) {
        if ($line =~ /^\s*#/) {
            next;
        }
        if ($line =~ /^\s*(\S(.*\S)?)\s*$/) {
            # Treat this as a library file.
            if (-e $1) {
                &info("I: Adding library $1.\n");
                push @python_libs, $1;
            } else {
                &err("E: Python library $1 does not exist (found in $libs_conf).\n");
            }
        }
    }
}

# --- Go ahead and run the application. ---

if ($ENV{PYTHONPATH}) {
    $ENV{PYTHONPATH} = "$python_lib_dir:$ENV{PYTHONPATH}";
} else {
    $ENV{PYTHONPATH} = $python_lib_dir;
}
&info("I: Using \$PYTHONPATH=$ENV{PYTHONPATH}.\n");

my @fullCommandLine = ( $python_cmd );

if ($script) {
    if (! -e $script) {
        &err("E: The script $script could not be found.\n");
        &usage();
    }
    my @fullCommandLine = ( $python_cmd, "$regina_home/scripts/runscript.py");
    push @fullCommandLine, @python_libs;
    push @fullCommandLine, ( '--', $script );
    push @fullCommandLine, @script_args;
    exec @fullCommandLine or &execError();
} else {
    my @fullCommandLine = ( $python_cmd, '-i',
        "$regina_home/scripts/runscript.py" );
    push @fullCommandLine, @python_libs;
    exec @fullCommandLine or &execError();
}

# --- Helper routines. ---

# Set various configuration options.
#
sub setVerbosity() {
    &info("I: Setting verbosity to $_[0].\n");
    if ($_[0] eq '0') {
        $quiet = 1;
        $verbose = 0;
    } elsif ($_[0] eq '1') {
        $quiet = 0;
        $verbose = 0;
    } elsif ($_[0] eq '2') {
        $quiet = 0;
        $verbose = 1;
    } else {
        &err("E: The verbosity level $_[0] is not recognised.\n");
        &err("E: This should be 0 (errors), 1 (errors/warnings) or 2 (everything).\n");
    }
}
sub setPythonCmd() {
    &info("I: Setting python command to $_[0].\n");
    $python_cmd = $_[0];
}
sub setPythonLibDir() {
    &info("I: Setting python module directory to $_[0].\n");
    if ( ! -e "$_[0]/regina.so") {
        &err("E: The calculation engine module 'regina.so' could not be \n");
        &err("   found in the directory $_[0].\n");
        &err("E: Please set \$REGINA_PYLIBDIR to the directory containing\n");
        &err("   the module 'regina.so' and try again.\n");
        exit 1;
    }
    $python_lib_dir = $_[0];
}
sub setReginaHome() {
    &info("I: Setting Regina home directory to $_[0].\n");
    if ( ! -e "$_[0]/scripts/runscript.py") {
        &err("E: \$REGINA_HOME should be set to the Regina base directory.\n");
        &err("   This is the directory containing the 'scripts' subdirectory,\n");
        &err("   the 'icons' subdirectory and so on.\n");
        &err("E: It is currently set to $regina_home.\n");
        exit 1;
    }
    $regina_home = $_[0];
}

# Write the given message to stderr if verbose mode is on.
#
sub info {
    if ($verbose) {
        print STDERR $_[0];
    }
}
# Write the given message to stderr if quiet mode is off.
#
sub warn {
    if (! $quiet) {
        print STDERR $_[0];
    }
}

# Write the given message to stderr.
#
sub err {
    print STDERR $_[0];
}

# Display usage information and exit.
#
sub usage {
    print STDERR "Usage: $prog_name [ -q, --quiet | -v, --verbose ]\n";
    print STDERR "       [ script [ script_args ... ]]\n";
    exit 1;
}

# The python interpreter could not be started.
#
sub execError() {
    &err("E: An error occurred whilst trying to start the Python interpreter.\n");
    &err("E: Run '$prog_name --verbose' to see more detailed diagnostic output,\n");
    &err("   including the runtime options being used.\n");
    &err("E: If you still cannot resolve the problem, please mail\n");
    &err("   $regina_support for assistance.\n");
}

