#!/usr/bin/perl
use lib qw (. .. ./lib);
use warnings;
use strict;


sub _process
{
    my $self  = shift;
    my $num   = shift || return;
    my @rates = $self->rates ($num);

    my ($str, $res);
    foreach my $rate (@rates)
    {
        $str = $self->dial_string ($num, $rate) || next;
        $res = $self->dial ($str);
        $res =~ /CHANUNAVAIL|CONGESTION/ ? next : last;
    }

    $res ||= 'CHANUNAVAIL';
    return $res;
}


package AGI::Fake;

sub new
{
    my $class = shift;
    return bless { @_ }, $class;
}


sub get_variable
{
    my $self = shift;
    my $var  = shift;
    return $self->{$var};
}


package main;
use Asterisk::LCR::Importer::CanonicalCSV;
use Asterisk::LCR::Rate;
use Config::Mini;


$SIG{__WARN__} = sub { $_[0] !~ /Can't locate AGI\/Fake\.pm/ and warn @_ };

@ARGV || die "Usage: $0 <config_file>";
Config::Mini::parse_file (@ARGV);

our $LOCALE    = Asterisk::LCR::Locale->new (Config::Mini::get ("dialer", "locale"));
our $STORE     = Config::Mini::instantiate ("storage")  || die "no storage configured"; 
our @PROVIDERS = map { Asterisk::LCR::Importer::CanonicalCSV->new ( %{$_} ) }
                 Config::Mini::select ('^import:');

our %prefixes = ();

foreach my $prov ( @PROVIDERS )
{
    foreach my $prfx ( $prov->prefixes() )
    {
        $prefixes{$prfx} = 1;
    }
}

my %fake_agi_args = ();
for my $prov (@PROVIDERS)
{
    print STDERR "Importing rates: " . $prov->target();
    print STDERR "\n";

    my $key = 'ASTERISK_LCR_TMPL_' . uc ($prov->provider());
    $fake_agi_args{$key} = [ $prov->{dial} ];
}

$Config::Mini::CONF{"agi"} = {
    package => [ "AGI::Fake" ],
    %fake_agi_args,
};

$Config::Mini::CONF{"dialer"}->{"lcr"} ||= [ "lcr_db" ];
$Config::Mini::CONF{"dialer"}->{"agi"} ||= [ Config::Mini::instantiate ("agi") ];

$| = 1;

my @out;
my $dialer = Config::Mini::instantiate ("dialer") || die "dialer object not defined";

print STDERR "Generating dialplan";
foreach my $prfx (sort keys %prefixes)
{
    print STDERR ".";
    my $local_prfx = $LOCALE ? $LOCALE->global_to_local ($prfx) : $prfx;
    
    my @dial_string  = @{$dialer->_process ($prfx)};
    my $count  = 1;
    foreach my $dial_string (@dial_string)
    {
        push @out, "exten => _$local_prfx". "X.,$count,Dial($dial_string)";
        $count++;
    }
}
print STDERR " done.\n";
print join "\n", sort { _sort_line ($b, $a) } @out;
print "\n";


sub _sort_line
{
    my $line1 = shift;
    my $line2 = shift;
    my ($prefix1) = $line1 =~ /_(.*?)X/;
    my ($prefix2) = $line2 =~ /_(.*?)X/;
    return 0  if (length ($prefix1) == length ($prefix2));
    return -1 if (length ($prefix1) < length ($prefix2));
    return +1 if (length ($prefix1) > length ($prefix2));
}


1;


__END__
