#!/usr/bin/perl
#/* ========================================
# * ███╗   ███╗██████╗ ██╗ █████╗ ██╗
# * ████╗ ████║██╔══██╗██║██╔══██╗██║
# * ██╔████╔██║██║  ██║██║███████║██║
# * ██║╚██╔╝██║██║  ██║██║██╔══██║██║
# * ██║ ╚═╝ ██║██████╔╝██║██║  ██║███████╗
# * ╚═╝     ╚═╝╚═════╝ ╚═╝╚═╝  ╚═╝╚══════╝
# * ========================================
# * mDial - Omni-Channel Contact Centre Suite.
# * Initially Written by Martin McCarthy.
# * Contributions welcome.
# * Active: 2020 - 2023.
# *
# * This software is licensed under AGPLv2.
# * You can find more information here;
# * https://www.gnu.org/licenses/agpl-3.0.en.html
# * A copy of the license is also shipped with this build.
# *
# * Important note: this software is provided to you free of charge.
# * If you paid for this software, you were ripped off.
# *
# * This project is a fork of the awesome FOSS project, ViCiDial.
# * ViCiDial is copyrighted by Matt Florell and the ViCiDial Group
# * under the AGPLv2 license.
# *
# * You can find out more about ViCiDial;
# * Web: https://www.vicidial.com/
# * Email: Matt Florell <vicidial@gmail.com>
# * IRC: Libera.Chat - ##vicidial
# *
# * Bug reports, feature requests and patches welcome!
# * ======================================== */
use strict;
my $script = 'agi_VDAD_local_optimize.agi';
my ( $servConf, $SYSLOG );
my %conf;
$conf{PATHconf} =
  '/etc/astguiclient.conf';   # default path to astguiclient configuration file:
open( CONF, $conf{PATHconf} )
  || die "can't open " . $conf{PATHconf} . ": " . $! . "\n";
while ( my $line = <CONF> ) {
    $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi;
    foreach my $key (
        qw( PATHhome PATHlogs PATHagi PATHweb PATHsounds PATHmontior
        VARserver_ip VARDB_server VARDB_database VARDB_user VARDB_pass VARDB_port)
      )
    {
        if ( $line =~ /^$key/ ) {
            $conf{$key} = $line;
            $conf{$key} =~ s/.*=//gi;
        }
    }
}
$conf{VARDB_port} = '3306' unless ( $conf{VARDB_port} );
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
  localtime(time);
$year = ( $year + 1900 );
$mon++;
if ( $mon < 10 )  { $mon  = "0$mon"; }
if ( $mday < 10 ) { $mday = "0$mday"; }
if ( $hour < 10 ) { $hour = "0$hour"; }
if ( $min < 10 )  { $min  = "0$min"; }
if ( $sec < 10 )  { $sec  = "0$sec"; }
my $SQLdate = "$year-$mon-$mday $hour:$min:$sec";
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
  localtime( time - 120 );
$year = ( $year + 1900 );
$mon++;
if ( $mon < 10 )  { $mon  = "0$mon"; }
if ( $mday < 10 ) { $mday = "0$mday"; }
if ( $hour < 10 ) { $hour = "0$hour"; }
if ( $min < 10 )  { $min  = "0$min"; }
if ( $sec < 10 )  { $sec  = "0$sec"; }
my $SQL2mindate = "$year-$mon-$mday $hour:$min:$sec";
use DBI;
use Asterisk::AGI;
use Time::HiRes ( 'gettimeofday', 'usleep', 'sleep' );
my ( $seconds, $microseconds ) = gettimeofday;
print STDERR "$seconds.$microseconds\n";
my $AGI  = new Asterisk::AGI;
my $dbhA = DBI->connect(
    "DBI:mysql:"
      . $conf{VARDB_database} . ":"
      . $conf{VARDB_server} . ":"
      . $conf{VARDB_port},
    $conf{VARDB_user},
    $conf{VARDB_pass}
) or die "Couldn't connect to database: " . DBI->errstr;
my $PADserver_ip = $conf{VARserver_ip};
$PADserver_ip =~ s/(\d+)(\.|$)/sprintf "%3.3d$2",$1/eg;
$PADserver_ip =~ s/\.//eg;
my %agi_vars            = $AGI->ReadParse();
my $channel             = $agi_vars{'channel'};
my $cid_name            = $agi_vars{'calleridname'};
my $connected_line_name = $agi_vars{'arg_1'};
my $extension           = $agi_vars{'extension'};
my $context             = $agi_vars{'context'};
my $uniqueid            = $agi_vars{'uniqueid'};
my $dest_channel        = "";
my $new_extension       = substr( $extension, 2 );
my $cid_channels_recent = 'cid_channels_recent';
my $CCRrec              = 0;
my $stmtA = "SHOW TABLES LIKE \"cid_channels_recent_$PADserver_ip\";";
my $sthA  = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$CCRrec = $sthA->rows;
$sthA->finish();

if ( $CCRrec > 0 ) {
    $cid_channels_recent = "cid_channels_recent_$PADserver_ip";
}
print STDERR "$CCRrec|$cid_channels_recent|$stmtA\n";
my $stmtA =
"SELECT dest_channel FROM $cid_channels_recent where (caller_id_name = '$cid_name' or connected_line_name = '$connected_line_name' or caller_id_name = '$connected_line_name' or connected_line_name = '$cid_name') and ( linkedid = '$uniqueid' or dest_uniqueid = '$uniqueid' or uniqueid = '$uniqueid') and call_date > '$SQL2mindate'";
my $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
print STDERR "$stmtA\n";
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
my $sthArows = $sthA->rows;
if ( $sthArows > 0 ) {
    my @aryA = $sthA->fetchrow_array;
    $dest_channel = $aryA[0];
}
$sthA->finish();
if ( $dest_channel ne "" ) {
    print STDERR "$sthArows|$dest_channel\n";
    $stmtA =
"INSERT INTO vicidial_manager values('','','$SQLdate','SENT','N','$conf{VARserver_ip}','','Redirect','$cid_name','Channel: $dest_channel','Context: $context','Exten: $new_extension','Priority: 1','','','','','','')";
    print STDERR "$stmtA\n";
    my $affected_rows = $dbhA->do($stmtA);
    my $man_id        = $dbhA->{'mysql_insertid'};
    $servConf = getServerConfig( $dbhA, $conf{VARserver_ip} );
    $SYSLOG   = 1 if ( $servConf->{vd_server_logs} =~ /Y/ );
    my $event_string = 'LOGGED INTO MYSQL SERVER ON 1 CONNECTION|';
    eventLogger( $conf{PATHlogs}, 'process', $event_string );
    my $cPATHlogs = $conf{PATHlogs};
    my $launch    = $conf{PATHhome} . "/AST_send_action_child.pl";
    $launch .= " --SYSLOG";
    $launch .= " --PATHlogs=" . $cPATHlogs;
    $launch .= " --telnet_host=" . $servConf->{telnet_host};
    $launch .= " --telnet_port=" . $servConf->{telnet_port};
    $launch .= " --ASTmgrUSERNAME=" . $servConf->{ASTmgrUSERNAME};
    $launch .= " --ASTmgrSECRET=" . $servConf->{ASTmgrSECRET};
    $launch .= " --ASTmgrUSERNAMEsend=" . $servConf->{ASTmgrUSERNAMEsend};
    $launch .= " --man_id=" . $man_id;
    $launch .= " --action=Redirect";
    $launch .= " --cmd_line_b='Channel: $dest_channel'";
    $launch .= " --cmd_line_c='Context: $context'";
    $launch .= " --cmd_line_d='Exten: $new_extension'";
    $launch .= " --cmd_line_e='Priority: 1'";
    eventLogger( $conf{'PATHlogs'}, 'launch',
        $launch . "  " . $cid_name . " " . $uniqueid . " " . $dest_channel );
    $launch .= " >> " . $conf{PATHlogs} . "/action_send." . logDate()
      if ($SYSLOG);
    system( $launch . ' &' );
    print STDERR "$launch\n";
    usleep( 1 * 10 * 1000 );
}
else {
    print STDERR
      "NO DestChannel for callid $cid_name|$agi_vars{'channel'}!!!\n";
}
$dbhA->disconnect();
exit;

sub getServerConfig {
    my ( $dbhA, $serverip ) = @_;
    my $stmtA =
"SELECT server_id,server_description,server_ip,active,asterisk_version,max_vicidial_trunks,telnet_host,telnet_port,ASTmgrUSERNAME,ASTmgrSECRET,ASTmgrUSERNAMEupdate,ASTmgrUSERNAMElisten,ASTmgrUSERNAMEsend,local_gmt,voicemail_dump_exten,answer_transfer_agent,ext_context,sys_perf_log,vd_server_logs,agi_output,vicidial_balance_active,balance_trunks_offlimits,recording_web_link,alt_server_ip,active_asterisk_server,generate_vicidial_conf,rebuild_conf_files,outbound_calls_per_second,sysload,channels_total,cpu_idle_percent,disk_usage,sounds_update,vicidial_recording_limit,carrier_logging_active,vicidial_balance_rank,rebuild_music_on_hold,active_agent_login_server,conf_secret FROM servers where server_ip = '"
      . $serverip . "';";
    my $sthA = $dbhA->prepare($stmtA) or die "preparing: " . $dbhA->errstr;
    $sthA->execute or die "executing: $stmtA " . $dbhA->errstr;
    my $servConf = $sthA->fetchrow_hashref;
    $SYSLOG = 1 if ( $servConf->{vd_server_logs} =~ /Y/ );
    $sthA->finish();
    return $servConf;
}

sub eventLogger {
    my ( $path, $type, $string ) = @_;
    open( LOG, ">>" . $path . "/action_" . $type . "." . logDate() )
      || die "Can't open "
      . $path
      . "/action_"
      . $type . "."
      . logDate() . ": "
      . $! . "\n";
    print LOG nowDate() . "|" . $string . "|\n";
    close(LOG);
}

sub logDate {
    my ($tms) = @_;
    my ( $sec, $min, $hour, $mday, $mon, $year ) = getTime($tms);
    return $year . '-' . $mon . '-' . $mday;
}

sub nowDate {
    my ($tms) = @_;
    my ( $sec, $min, $hour, $mday, $mon, $year ) = getTime($tms);
    return $year . '-' . $mon . '-' . $mday . ' ' . $hour . ':' . $min . ':'
      . $sec;
}

sub getTime {
    my ($tms) = @_;
    $tms = time unless ($tms);
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
      localtime($tms);
    $year += 1900;
    $mon++;
    $mon  = "0" . $mon  if ( $mon < 10 );
    $mday = "0" . $mday if ( $mday < 10 );
    $min  = "0" . $min  if ( $min < 10 );
    $sec  = "0" . $sec  if ( $sec < 10 );
    return ( $sec, $min, $hour, $mday, $mon, $year );
}
