#!/usr/bin/perl 
$|=1;

use DBI;
use Switch;
use FindBin qw($Bin);
use POSIX qw/strftime/;
use Time::Local;

our $messaggi = 0;
while( $_ = shift @ARGV ) {
	our $messaggi	= 1	if /^\-v$/;
	$start		= 1	if /^\-i$/;
}

my $tabella 		= "proxy_dati_storico";
my $tabella_orig 	= "proxy_dati";
my $campo 		= "data_destroy";
my $limitgg		= 30;

open CONFFILE, "< $Bin/../core/config.php" or die ("Manca file di configurazione\n");
while (<CONFFILE>) {
        if(/^\$db_data_server = "(\S+)"/ ) {
                our $db_host = $1;
        }
        if(/^\$db_data_name = "(\S+)"/ ) {
                our $db_name = $1;
        }
        if(/^\$db_data_user = "(\S+)"/ ) {
                our $db_user = $1;
        }
        if(/^\$db_data_pwd = "(\S+)"/ ) {
                our $db_pass = $1;
        }
}
close CONFFILE;

my $dbmysql = DBI->connect("DBI:mysql:;host=$db_host", "$db_user", "$db_pass") or die ($DBI::errstr);
$sts = $dbmysql->prepare("use $db_name");
$sts->execute ();

if ($start) {
	inizializza($dbmysql, $tabella, $campo, $tabella_orig);
	exit;	
}

aggiorna($dbmysql, $tabella, $campo, $tabella_orig);
exit;


sub inizializza {

	my $dbmysql 		= shift;
	my $tabella 		= shift;
	my $campo 		= shift;
	my $tabella_orig 	= shift;

	printf  "Inizio attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);

	$copia 		= "INSERT INTO $tabella SELECT * FROM $tabella_orig WHERE $campo > '1970-01-01 00:00:00' AND $campo < DATE_SUB(NOW(), INTERVAL 1 DAY)";
	$rimuovi	= "DELETE FROM $tabella_orig WHERE $campo > '1970-01-01 00:00:00' AND $campo < DATE_SUB(NOW(), INTERVAL 1 DAY)";
	$sts = $dbmysql->prepare($copia);
	$sts->execute ();
	$sts = $dbmysql->prepare($rimuovi);
	$sts->execute ();

	$part = "ALTER TABLE $tabella PARTITION BY RANGE ( TO_DAYS($campo) ) (\n";

	$query = "	SELECT 
				DATE_FORMAT($campo, \"%Y%m%d\") AS giorno, 
				DATE_FORMAT($campo, '%Y-%m-%d') AS partenza
			FROM 
				$tabella
			GROUP BY 
				giorno
			ORDER BY 
				giorno
		";

	$sts = $dbmysql->prepare($query);
	$sts->execute ();
	while (my $dato = $sts->fetchrow_hashref) {
		my $giorno = $$dato{'giorno'};
		my $partenza = $$dato{'partenza'};
		$part .= "\tPARTITION p$giorno VALUES LESS THAN ( TO_DAYS('$partenza') ),\n";
	}
	$part .= "\tPARTITION p99999999 VALUES LESS THAN (MAXVALUE)\n";
	$part .= ");\n";
	
	print $part if ($messaggi);
	
	printf  "Inizio partizionamento %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);
	$sts = $dbmysql->prepare($part);
	$sts->execute ();

	printf  "Termine attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);
}

sub aggiorna {
	my $dbmysql = shift;
	my $tabella = shift;
	my $campo = shift;
	my $tabella_orig 	= shift;

	printf  "Inizio attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);

	$copia 		= "INSERT INTO $tabella SELECT * FROM $tabella_orig WHERE $campo > '1970-01-01 00:00:00' AND $campo < DATE_SUB(NOW(), INTERVAL 1 DAY)";
	$rimuovi	= "DELETE FROM $tabella_orig WHERE $campo > '1970-01-01 00:00:00' AND $campo < DATE_SUB(NOW(), INTERVAL 1 DAY)";
	$sts = $dbmysql->prepare($copia);
	$sts->execute ();
	$sts = $dbmysql->prepare($rimuovi);
	$sts->execute ();

	$query = "SHOW CREATE TABLE $tabella";
	$sts = $dbmysql->prepare($query);
	$sts->execute ();

	my @row = $sts->fetchrow_array();
	my @risp = split '\n', $row[1];

	my $ultimo = "";
	foreach $riga (@risp) {
		if ($riga =~ /^[\(\s]?PARTITION p(\d{4})(\d{2})(\d{2}) VALUES LESS THAN \(\d+\) .*$/) {
			my $p = "$1$2$3";
			next if ($p eq '19700101');
			
			$ultimo = "$1-$2-$3";
			my $diff = diffgg ($ultimo);

			if ($diff > $limitgg) {
				my $query = "ALTER TABLE $tabella DROP PARTITION p$1$2$3";
				print "$query\n";
				$sts = $dbmysql->prepare($query);
				$sts->execute ();
			}
		}
	}

	if (diffgg($ultimo) > -5) {
		my $prequery = "ALTER TABLE $tabella REORGANIZE PARTITION p99999999 INTO (\n";
		my $postquery = "PARTITION p99999999 VALUES LESS THAN (MAXVALUE))\n";
		my $inquery = "";

		while (diffgg($ultimo) > -5) {
			$ultimo = addgg ($ultimo);
			my @tmp0 = split / /, $ultimo;
			my @tmp = split /-/, $tmp0[0];
			my $p = $tmp[0].$tmp[1].$tmp[2];
			$inquery .= "PARTITION p$p VALUES LESS THAN ( TO_DAYS('$ultimo') ),\n";
		}
		$query = "$prequery$inquery$postquery";
		print "$query\n" if ($messaggi);
		$sts = $dbmysql->prepare($query);
		$sts->execute ();

	}

	printf  "Inizio attivita' pulizia %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);
		$query = "	DELETE FROM 
					proxy_dati 
				WHERE 
					data_new < DATE_SUB(NOW(), INTERVAL 1 DAY) 
				AND 
					data_destroy = '1970-01-01 00:00:00';
		";
		$sts = $dbmysql->prepare($query);
		$sts->execute ();

	printf  "Termine attivita' %s\n",strftime('%d-%m-%Y %H:%M:%S',localtime) if ($messaggi);
}

sub diffgg {
	my $data = shift;

	my @today = localtime();
	my $time = timelocal(@today);

	my @part = split /-/, $data;
	my @tempo = (59, 59, 23, $part[2], $part[1]-1, $part[0]-1900);
	my $tempo = timelocal(@tempo);

	return int(($time - $tempo) / 86400);
}

sub addgg {
	my $data = shift;

	my @part = split /-/, $data;
	my @tempo = (59, 59, 23, $part[2], $part[1]-1, $part[0]-1900);
	my $tempo = timelocal(@tempo) + 86400;
	return strftime('%Y-%m-%d',localtime($tempo))
}
