package LIMS::Dispatch;

use base 'CGI::Application::Dispatch';

use IO::Dir;
use Data::Dumper;
use LIMS::Local::Utils;
use Time::HiRes qw(gettimeofday tv_interval);

BEGIN {
	use LIMS::Local::ErrorHandler; # can't be used with CAP::Redirect or get
	# use CGI::Carp qw(fatalsToBrowser);
	# "prerun_mode() can only be called within cgiapp_prerun()! Error at
	# CAP::Redirect.pm line 24" - ($SIG{__DIE__} issue - see README)
}

# map for translate_module_name():
my %map = (
	worklist => 'WorkList', # action_links in header.tt
	printrun => 'PrintRun',
);

# CAPITALISE these (also for translate_module_name):
my @capitalised = qw(pas hmrn);

my $path_to_app_root = LIMS::Local::Utils::find_home(); # warn 'path_to_app_root:'.$path_to_app_root;

my $debug = ! grep $ENV{$_}, qw(HARNESS_ACTIVE FAST_CGI MOD_PERL); # saves *.t dumping data to console

my $d = IO::Dir->new($path_to_app_root . '/config')
	|| die "undefined \$d in $0", $@;

my @config_files =
    map { $path_to_app_root . '/config/' . $_ }
        grep { $_ =~ /lims_(.*)\.pl$/ } # lims_*.pl
            $d->read; # warn Dumper \@config_files;

my @dispatch_table = (
    # specific rm's that don't match :app/:rm
    '/'    => { app => 'Search', rm => 'default' }, # if no path_info supplied - should be handled by default arg ?
    logout => { app => 'Login', rm => 'logout' },

    'admin/:app'        => { prefix => 'LIMS::Controller::Admin' },
    'admin/:app/:rm'    => { prefix => 'LIMS::Controller::Admin' },
    'admin/:app/:rm/:id'=> { prefix => 'LIMS::Controller::Admin' },

    'config/:app'        => { prefix => 'LIMS::Controller::Admin::Config' },
    'config/:app/:rm'    => { prefix => 'LIMS::Controller::Admin::Config' },
    'config/:app/:rm/:id'=> { prefix => 'LIMS::Controller::Admin::Config' },

    ':app/=/:id' => { rm => 'load' }, # make '=' alias for 'load'
	
    # generic matches:
    ':app' => { }, # LIMS::Controller::<default runmode>
    ':app/:rm' => { }, # LIMS::Controller::<specified runmode>
    ':app/:rm/:id' => { }, # LIMS::Controller::<specified runmode>; token = $obj->param('id')
    ':app/:rm/:id/:Id' => { }, # as above; token = $c->param('id') & $obj->param('Id')
);

my %local_args = (
#   default => 'search', # fastcgi doesn't work unless '/' set in dispatch table
    prefix  => 'LIMS::Controller',
    table   => \@dispatch_table,
    debug   => $debug,
    args_to_new => {
       PARAMS => {
            config_files => \@config_files,
#            t0 => [gettimeofday], # no point if using CAD::Server - increments
       },
    },
);

sub dispatch_args {
	my $self = shift;

	my $dispatch_args = $self->SUPER::dispatch_args;

	# override default dispatch_args with %local_args:
	$dispatch_args->{$_} = $local_args{$_} for keys %local_args;
	# warn Dumper $dispatch_args;

	return $dispatch_args;
}

# override default method - can return module_name in different format to default:
sub translate_module_name {
    my ($self, $input) = @_; # warn $input;

	# return value from %map if defined:
	return $map{$input} if defined $map{$input};
	
	# force capitalisation if required:
	map { $input =~ s/$_/uc($_)/e } @capitalised;
	
    $input = join('::', map { ucfirst($_) } split(/_/, $input));
    $input = join('',   map { ucfirst($_) } split(/-/, $input));

    return $input;
}

sub throw_bad_request {
	return 1;
}

1;