#!/usr/bin/perl -CSD
# Purpose: template toolkit helper script
################################################################################

use strict;
use warnings;
use English;
use YAML::XS qw(LoadFile);
use Template;
use Hash::Merge qw(merge);
use DBI;

sub sync_extra_sockets;
sub db_connect;
my $dbh;

my $tt = Template->new({ ABSOLUTE => 1, RELATIVE => 1 });

my $config = {};
foreach my $file (@ARGV) {
  $config = merge($config, LoadFile($file));
}
# rw connection to central node
my $dbhost = $config->{database}->{central}->{dbhost};
my $dbport = $config->{database}->{central}->{dbport};

open my $SWFH, '<', '/etc/mysql/sipwise.cnf';
my $dbpass = join ' ', <$SWFH>;
close $SWFH;
$dbpass =~ s/^.*SIPWISE_DB_PASSWORD=\'([^\']+)\'.*$/$1/;
chomp $dbpass;
my $dbuser = 'sipwise';
my $dbname = $config->{ossbss}->{provisioning}->{database}->{name};

unless(defined $dbhost) {
  print "Error: Could not determine provisioning db hostname\n";
  exit 1;
}
unless(defined $dbport) {
  print "Error: Could not determine provisioning db port\n";
  exit 1;
}
unless(defined $dbname) {
  print "Error: Could not determine provisioning db name\n";
  exit 1;
}
unless(defined $dbuser) {
  print "Error: Could not determine provisioning db user\n";
  exit 1;
}
unless(defined $dbpass) {
  print "Error: Could not determine provisioning db password\n";
  exit 1;
}

$dbh = db_connect();

exit 1 unless(sync_extra_sockets($dbh,
  $config->{kamailio}->{lb}->{extra_sockets}));

exit 1 unless(sync_rtp_interfaces($dbh,
  { map {$_ => $_} @{$config->{rtp_interfaces}} } ));

$dbh->disconnect;

exit 0;

sub db_connect
{
	my $dbh = DBI->connect("DBI:mysql:database=${dbname};host=${dbhost};port=${dbport}",
						$dbuser, $dbpass, { PrintError => 1 });
	unless(defined $dbh) {
		print "Error: Could not connect to database '$dbname' at '$dbhost:$dbport' as '${dbuser}': $DBI::errstr\n";
		exit 1;
	}
	return $dbh;
}

sub generic_enum_sync {
	my $dbh = shift;
	my $config_hash = shift;
	my $pref_name = shift;
	my $sth = $dbh->prepare("select id from voip_preferences where attribute=?");
	$sth->execute($pref_name);
	my $res = $sth->fetchrow_hashref();
	unless(defined $res) {
	  print "Error: Could not find preference '$pref_name' in db\n";
	  return;
	}
	my $pref_id = $res->{id};
	$sth->finish;

	my $enum_insert_sth = $dbh->prepare("insert into voip_preferences_enum (preference_id, label, value, usr_pref, dom_pref, peer_pref) values(?, ?, ?, 1, 1, 1)");
	my $enum_update_sth = $dbh->prepare("update voip_preferences_enum set value=? where id=?");
	my $enum_delete_sth = $dbh->prepare("delete from voip_preferences_enum where id=?");
	$sth = $dbh->prepare("select id, label, value from voip_preferences_enum where preference_id=?");
	$sth->execute($pref_id);

	my $db_hash = $sth->fetchall_hashref('label');
	$sth->finish;

	foreach my $row (keys %{$db_hash}) {
	  $row = $db_hash->{$row};
	  next if($row->{label} eq 'default');
	  if(!exists $config_hash->{$row->{label}}) {
	    print "$pref_name $row->{label} does not exist anymore in config, delete from db\n";
	    $enum_delete_sth->execute($row->{id});
	  } elsif($config_hash->{$row->{label}} ne $row->{value}) {
	    print "update $pref_name $row->{label}=$row->{value} to $row->{label}=$config_hash->{$row->{label}} in db\n";
	    $enum_update_sth->execute($config_hash->{$row->{label}}, $row->{id});
	    delete $config_hash->{$row->{label}};
	  } else {
	    print "$pref_name $row->{label}=$row->{value} is sync between config and db\n";
	    delete $config_hash->{$row->{label}};
	  }
	}
	foreach my $label(keys %{$config_hash}) {
	  print "insert new $pref_name $label=$config_hash->{$label} from config into db\n";
	  $enum_insert_sth->execute($pref_id, $label, $config_hash->{$label});
	}

	$enum_insert_sth->finish;
	$enum_update_sth->finish;
	$enum_delete_sth->finish;
	return 1;
}

## kamailio.lb.extra_sockets handling: ##############################
sub sync_extra_sockets {
	return generic_enum_sync(@_, 'outbound_socket');
}

## rtp_* interfaces handling: ##############################
sub sync_rtp_interfaces {
	return generic_enum_sync(@_, 'rtp_interface');
}

## END OF FILE #################################################################
