#!/usr/bin/perl

use strict;
use warnings;

use IO::Socket::INET;
use Getopt::Long;
use Config::Tiny;

my $ip;
my $port;
my $conffile = '/etc/rtpengine/rtpengine.conf';
my $listen;

Getopt::Long::Configure('require_order');

my $optret = GetOptions(
    'help|h'              => sub { showusage(); exit 0; },
    'ip=s'                => \$ip,
    'port=i'              => \$port,
    'config-file=s'       => \$conffile,
);

if (-f $conffile) {
    my $config = Config::Tiny->read($conffile);
    $config or die "Failed to read config file: " . Config::Tiny->errstr;

    $listen = $config->{rtpengine}{'listen-cli'}
        if $config->{rtpengine};
    if ($listen =~ /^\d+$/) {
        $port //= $listen;
    }
    else {
        $ip //= $listen;
    }
}

if ($ip && $ip =~ s/:(\d+)$// && !$port) {
    $port = $1;
}

my $argumentstring = "@ARGV";
$argumentstring = trim($argumentstring);

$ip //= '127.0.0.1';
$port //= 9900;

if (!$argumentstring || !$optret || $port <= 0 || $port > 65535) {
    showusage();
    exit 1;
}

# create a connecting socket
my $socket = new IO::Socket::INET (
    PeerHost => $ip,
    PeerPort => $port,
    Proto => 'tcp',
);
die "Cannot connect to rtpengine $!\n" unless $socket;

$socket->autoflush(1);

#set send/recv timeout so script doesn't hang when rtpengine doesn't interact
setsockopt($socket, SOL_SOCKET, SO_SNDTIMEO, pack('L!L!', 3, 0) ) or die $!;
setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack('L!L!', 3, 0) ) or die $!;

my $size = $socket->send("$argumentstring\n");
 
# receive a response of up to 10MB
my $response = "";

do {
   $response = "";
   $socket->recv($response, 1024*1024*10);
   print $response; 
} while ( not $response eq "");

$socket->close();

sub showusage {
    print "\n";
    print "    rtpengine-ctl [ -ip <ipaddress>[:<port>] -port <port> ] <command>\n";
    print "\n";
    print "    Supported commands are:\n";
    print "\n";
    print "    help                       : generated complete list of commands\n";
    print "\n";
    print "    list <option>\n";
    print "         help                  : generated complete list of sub-commands\n";
    print "         numsessions           : print the number of sessions\n";
    print "         maxsessions           : print the number of allowed sessions\n";
    print "         maxopenfiles          : print the number of allowed open files\n";
    print "         maxcpu                : print maxmimum CPU usage allowed\n";
    print "         maxload               : print maxmimum load average allowed\n";
    print "         maxbw                 : print maxmimum bandwidth usage average allowed\n";
    print "         sessions <callid>     : print detail about one session\n";
    print "         sessions all          : print one-liner all sessions information\n";
    print "         sessions own          : print one-liner own sessions information\n";
    print "         sessions foreign      : print one-liner foreign sessions information\n";
    print "         totals                : print total statistics\n";
    print "         jsonstats             : print total statistics in JSON format\n";
    print "         timeout               : print timeout parameter\n";
    print "         silenttimeout         : print silent-timeout parameter\n";
    print "         finaltimeout          : print final-timeout parameter\n";
    print "         offertimeout          : print offer-timeout parameter\n";
    print "         loglevels             : print available log levels\n";
    print "         loglevel              : print current log levels\n";
    print "         loglevel <system>     : print one current log level\n";
    print "         redisallowederrors    : print redis-allowed-errors parameter\n";
    print "         redisdisabletime      : print redis-disable-time parameter\n";
    print "         redisconnecttimeout   : print redis-connect-timeout parameter\n";
    print "         rediscmdtimeout       : print redis-cmd-timeout parameter\n";
    print "         controltos            : print control-tos parameter\n";
    print "         deletedelay           : print delete-delay parameter\n";
    print "         interfaces            : print local interface/port statistics\n";
    print "         transcoders           : print transcoding statistics\n";
    print "\n";
    print "    get                        : get is an alias for list, same parameters apply\n";
    print "\n";
    print "    terminate <option>\n";
    print "         <callid>              : session is immediately terminated\n";
    print "         all                   : terminates all current sessions\n";
    print "         own                   : terminates own current sessions\n";
    print "         foreign               : terminates foreign current sessions\n";
    print "\n";
    print "    set <option>\n";
    print "         help                  : generated complete list of sub-commands\n";
    print "         maxsessions  <int>    : set the max nr of allowed sessions\n";
    print "         maxopenfiles <uint>   : set the max nr of allowed open files\n";
    print "         maxcpu <float>        : set maxmimum CPU usage allowed\n";
    print "         maxload <float>       : set maxmimum load average allowed\n";
    print "         maxbw <uint>          : set maxmimum bandwidth usage average allowed\n";
    print "         timeout <uint>        : set the --timeout parameter \n";
    print "         silenttimeout <uint>  : set the --silent-timeout parameter \n";
    print "         finaltimeout <uint>   : set the --final-timeout parameter \n";
    print "         offertimeout <uint>   : set the --offer-timeout parameter \n";
    print "         loglevel <uint>       : set all log levels to new value (1-7)\n";
    print "         loglevel <sys> <uint> : set one log level to new value (1-7)\n";
    print "         redisallowederrors    : set the --redis-allowed-errors parameter\n";
    print "         redisdisabletime      : set the --redis-disable-time parameter\n";
    print "         redisconnecttimeout   : set the --redis-connect-timeout parameter\n";
    print "         rediscmdtimeout       : set the --redis-cmd-timeout parameter\n";
    print "         controltos            : set the --control-tos parameter\n";
    print "         deletedelay           : set the --delete-delay parameter\n";
    print "\n";
    print "    params <option>\n";
    print "         start                 : lists the initial values of all the configuration file parameters\n";
    print "         current               : lists the present values of all the configuration file parameters\n";
    print "         diff                  : compares initial and present values of all the configuration file parameters and lists the updated parameters\n";
    print "         revert                : reverts the values of all the configuration file parameters to their initial values\n";
    print "\n";
    print "    ksadd [ keyspace <uint>]\n";
    print "         keyspace <uint>       : subscribe to 'keyspace' database\n";
    print "\n";
    print "    ksrm [ keyspace <uint>]\n";
    print "         keyspace <uint>       : unsubscribe to 'keyspace' database\n";
    print "                               : remove all foreign calls for that 'keyspace'\n";
    print "\n";
    print "    kslist                     : print all currently subscribed keyspaces\n";
    print "\n";
    print "    active                     : set all running sessions to 'owned'\n";
    print "    standby                    : set all running sessions to 'foreign'\n";
    print "\n";
    print "    debug <callid> <on/off>    : set debugging flag for given call\n";
    print "\n";
    print "\n";
    print "    Return Value:\n";
    print "    0 on success with output from server side, other values for failure.\n";
    print "\n";
}

sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };