#!/usr/bin/perl -w
#Periodic process

use vars  qw(%RAD %conf @MODULES $db $html $DATE $GZIP $MYSQLDUMP %ADMIN_REPORT $DEBUG);
#use strict;
use FindBin '$Bin';
use Sys::Hostname;

require $Bin . '/config.pl';
unshift(@INC, $Bin . '/../', $Bin . '/../Abills', $Bin . "/../Abills/$conf{dbtype}");

require "Abills/defs.conf";
require "Abills/templates.pl";

require Abills::Base;
Abills::Base->import();
my $begin_time = check_time();


require Abills::SQL;
Abills::SQL->import();
require Users;
Users->import();
require Admins;
Admins->import();
require Abills::HTML;
Abills::HTML->import();
$html = Abills::HTML->new({ CONF => \%conf });

my $sql = Abills::SQL->connect($conf{dbtype}, $conf{dbhost}, $conf{dbname}, $conf{dbuser}, $conf{dbpasswd});
my $db = $sql->{db};
my $admin = Admins->new($db, \%conf);
$admin->info($conf{SYSTEM_ADMIN_ID}, { IP => '127.0.0.1' });



if ($admin->{errno}) {
	print  $admin->{errno};
	exit 0;
}

my $users = Users->new($db, $admin, \%conf); 

require "language/$conf{default_language}.pl";
use POSIX qw(mktime strftime);
my $YESTERDAY = (strftime "%Y-%m-%d", localtime(time - 86400));

%ADMIN_REPORT = (DATE => $DATE);
my $args = parse_arguments(\@ARGV);
$ADMIN_REPORT{HOSTNAME}=hostname();

#print $DATE;

my @daily_functions=(
                     'admin_report_daily'
                     );

my @monthly_functions = ('admin_report_monthly',
                         'backup',
                         'logrotate');
my @reports = ();

#make periodic oparation only for selected modules
if ($args->{MODULES}) {
	$args->{MODULES}=~s/ //g;
	@MODULES = split(/,/, $args->{MODULES});
}

#Don't process for this modules
my @SKIP_MODULES = ();
if ($args->{SKIP_MODULES}) {
	$args->{SKIP_MODULES}=~s/ //g;
	@SKIP_MODULES = split(/,/, $args->{SKIP_MODULES});
}



if ($args->{DEBUG}) {
  $DEBUG = '';
}




  foreach my $m (@MODULES) {
    next if(in_array($m, \@SKIP_MODULES));

  	require "Abills/modules/$m/config";
 
    my $i=0;
    while(my($k, $v)= each %PERIODIC) {
      if ($k eq 'daily') {
        foreach my $funtion_name (@{ $PERIODIC{$k} })  {
          push @daily_functions, $funtion_name;
         }
       }
      elsif ($k eq 'monthly') {
        foreach my $funtion_name (@{ $PERIODIC{$k} })  {
          push @monthly_functions, $funtion_name;
         }
       }
      elsif ($k eq 'report') {
        foreach my $funtion_name (@{ $PERIODIC{$k} })  {
          push @reports, $funtion_name;
         }      
       }
      $i++;
     }

   if($i > 0) {
     #Language pack
     my $lang_file = '';
     foreach my $prefix (@INC) {
       my $realfilename = "$prefix/Abills/modules/$m/lng_$html->{language}.pl";
       if (-f $realfilename) {
         $lang_file =  $realfilename;
         require $lang_file;
         last;
        }
       }

     if ($lang_file eq '' && -f "Abills/modules/$m/lng_english.pl" ) {
       require "Abills/modules/$m/lng_english.pl";
      }
     
 	   require "Abills/modules/$m/webinterface";
    }
   undef %PERIODIC;
  }

push  @daily_functions, 'sheduler';
my($Y, $M, $D);
  if(defined($args->{DATE})) {
     if ($args->{DATE} !~ /\d{4}\-\d{2}\-\d{2}/) {
       print "Wrong date format. Format: YYYY-MM-DD\n";
       exit;
      }
     ($Y, $M, $D)=split(/-/, $args->{DATE}, 3);
     $YESTERDAY = (strftime '%Y-%m-%d', localtime(POSIX::mktime( 0, 10, 1, $D, ($M-1), ($Y-1900)) - 86400));

     #$YESTERDAY=$args->{DATE};
     $ADMIN_REPORT{DATE} = $args->{DATE};
   }
  
  if (defined($args->{NO_USERS_WARNINGS})) {
    $ADMIN_REPORT{NO_USERS_WARNINGS}=1;
   }

  ($Y, $M, $D)=split(/-/, $ADMIN_REPORT{DATE}, 3);
 
 
if (defined($args->{monthly})) {
  for(my $i=$#monthly_functions; $i>-1; $i--) {
  	my $f = $monthly_functions[$i];
  	#print $f . "\n";
  	$f->({ DEBUG => $args->{DEBUG} });
  }

  if ($begin_time > 0)  {
    Time::HiRes->import(qw(gettimeofday));
    my $end_time = gettimeofday();
    my $gen_time = $end_time - $begin_time;
    $ADMIN_REPORT{GT} = sprintf(" GT: %2.5f", $gen_time);
   }
  if (! $args->{NO_ADM_REPORT}) {
    my $message = $html->tpl_show(templates('admin_report_month'), \%ADMIN_REPORT, { notprint => 'yes' });
    sendmail("$conf{ADMIN_MAIL}", "$conf{ADMIN_MAIL}", "$ADMIN_REPORT{HOSTNAME}: Monthly billing report", 
              "$message", "$conf{MAIL_CHARSET}", "2 (High)");
   }
 }
elsif (defined($args->{daily})) {
  for(my $i=$#daily_functions; $i>-1; $i--) {
        my $f = $daily_functions[$i];
        #print $f . "\n";
        $f->({ DEBUG => $args->{DEBUG} });
   }

  if ($begin_time > 0)  {
    Time::HiRes->import(qw(gettimeofday));
    my $end_time = gettimeofday();
    my $gen_time = $end_time - $begin_time;
    $ADMIN_REPORT{GT} = sprintf(" GT: %2.5f", $gen_time);
  }

  if (! $args->{NO_ADM_REPORT}) {
    my $message = $html->tpl_show(templates('admin_report_day'), \%ADMIN_REPORT, { notprint => 'yes' });
    sendmail("$conf{ADMIN_MAIL}", "$conf{ADMIN_MAIL}", "$ADMIN_REPORT{HOSTNAME}: Daily billing report ($YESTERDAY)", 
             "$message", "$conf{MAIL_CHARSET}", "2 (High)");
   }
} 
elsif (defined($args->{backup})) {
  backup();	
 }
else {
 print "Arguments (daily|monthly|backup)
   Optional arguments
   DATE=2005-10-01            - Date for periodic process
   NO_USERS_WARNINGS          - Don't send user warning messages
   MODULES=[modules_list,...] - Make periodic process only for this modules
   SKIP_MODULES=[modules_list]- Skip this module in periodic proccess
   NO_ADM_REPORT              - Don't send report to admin via e-mail
   DEBUG                      - Show debug output\n";
 exit;
}


if ($args->{DEBUG}) {
	print "DEBUG MODE: $args->{DEBUG}\n";
	print $DEBUG;
}

#**********************************************************
# sheduler()
#**********************************************************
sub sheduler {
	
	
my %shedule_type = ('tp'      => $_VARIANT, 
                    'fees'    => $_FEES,
                    'message' => $_MESSAGES
 );

#Change tp
 require Shedule;
 Shedule->import();
 my $shedule = Shedule->new($db, $admin, \%conf);

 require Fees;
 Fees->import();
 my $fees = Fees->new($db, $admin, \%conf);


 my $list = $shedule->list({ Y => $Y,
 	                           M => $M,
 	                           D => $D, 
 	                           PAGE_ROWS => 100000 });

 $ADMIN_REPORT{SHEDULE}=sprintf("%-14s| %-12s| %-8s| %-14s|%-14s|\n", "$_LOGIN", "$_MODULES", "$_TYPE", "$_VALUE", "$_ADMIN");
 $ADMIN_REPORT{SHEDULE}.= "---------------------------------------------------------\n";
 foreach my $line (@$list) {
   if ($line->[6] eq 'fees') {
    	 my $user = $users->info( $line->[12] );
    	 my ($sum, $descr) = split(/:/, $line->[7], 2);
    	 #my $module = $line->[8];
    	 $fees->take($user, $sum, { DESCRIBE => "$_SHEDULE: $descr" } );  
     }
   #Required modules
   elsif ($line->[8] ne '') {
    	 my $function = lc  $line->[8] . "_sheduler";
    	 $function->($line->[6], "$line->[7]", $line->[12]);
     }
 	 $shedule->del({ ID => $line->[13] });

	  $ADMIN_REPORT{SHEDULE}.=sprintf("%-14s| %-12s| %-8s| %-14s|\n", 
	    $line->[5], $line->[8], $line->[6], $line->[7], $line->[9]);
  } 

}








#**********************************************************
# admin_report_daily
#**********************************************************
sub admin_report_daily {



##closed users account
#$ADMIN_REPORT{CLOSED} = sprintf ("%-14s| %4s|%-20s| %9s| %8s| %19s|\n", $_LOGIN, 'V', 
#     $_NAME, $_DEPOSIT, $_CREDIT, $_LAST_LOGIN);
#$ADMIN_REPORT{CLOSED}.= "---------------------------------------------------------\n";
#my %LIST_PARAMS = ( DISABLE => 'y' ) ;
#$LIST_PARAMS{PAGE_ROWS}=10000;
#
#my $list = $users->list( { %LIST_PARAMS } );
#foreach my $line (@$list) {
#   $ADMIN_REPORT{CLOSED} .= sprintf ("%-14s| %4d|%-20s| %9.4f| %8.2f| %19s|\n", 
#     $line->[0], 
#     $line->[9], 
#     $line->[4], 
#     $line->[2], 
#     $line->[3], 
#     $line->[10]);
#}
#$ADMIN_REPORT{CLOSED} .= "---------------------------------------------------------\n$_TOTAL: $users->{TOTAL}\n";


#Payments
require Finance;
Finance->import();
my $payments = Finance->payments($db, $admin, \%conf); 

$ADMIN_REPORT{PAYMENTS}  =  sprintf("%-14s| %8s| %20s| %12s| %15s| %19s|\n", $_LOGIN, $_SUM, 
    $_DESCRIBE, 'Admins.', 'IP', $_DATE);
$ADMIN_REPORT{PAYMENTS} .= "---------------------------------------------------------\n";

$LIST_PARAMS{DATE}=$YESTERDAY;
$LIST_PARAMS{SORT}=2;
$LIST_PARAMS{DESC}='DESC';
$LIST_PARAMS{PAGE_ROWS}=10000;

$list = $payments->list( { %LIST_PARAMS } );

foreach my $line (@$list) {
   $ADMIN_REPORT{PAYMENTS} .= sprintf ("%-14s| %8.4f| %20s| %12s| %15s| %19s|\n", 
    "$line->[1]", 
    "$line->[3]", 
    "$line->[4]", 
    "$line->[5]", 
    "$line->[6]", 
    "$line->[2]");
}

$ADMIN_REPORT{PAYMENTS} .= "---------------------------------------------------------\n";
$ADMIN_REPORT{PAYMENTS} .= sprintf("%-14s| %8s|\n%-14s| %8s|\n", 
  $_TOTAL, $payments->{TOTAL},
  $_SUM,   $payments->{SUM});



#Fees
my $fees = Finance->fees($db, $admin, \%conf);


# Daily fees
$ADMIN_REPORT{FEES} .= sprintf ("%-14s| %8s| %20s| %12s| %15s| %8s\n", $_LOGIN, $_SUM, $_DESCRIBE, $_ADMINS, 'IP', $_DEPOSIT);
$ADMIN_REPORT{FEES} .= "---------------------------------------------------------\n";

$LIST_PARAMS{PAGE_ROWS}=10000;
$list = $fees->list( { %LIST_PARAMS } );
foreach my $line (@$list) {
#SELECT f.id, u.id, f.date, f.sum, f.dsc, a.name, INET_NTOA(f.ip), f.last_deposit, f.uid 
  $ADMIN_REPORT{FEES} .= sprintf ("%-14s| %8.4f| %20s| %12s| %15s| %8.4f\n", 
    $line->[1], 
    $line->[3], 
    $line->[4], 
    $line->[5], 
    $line->[6],
    $line->[7]);
    
}

$ADMIN_REPORT{FEES} .= "---------------------------------------------------------\n";
$ADMIN_REPORT{FEES} .= sprintf("%-14s| %8s|\n%-14s| %8s|\n", 
    $_TOTAL, $fees->{TOTAL}, 
    $_SUM,   $fees->{SUM});


#Module report functions
foreach my $function (@reports) {
	$ADMIN_REPORT{MODULES} .= $function->('daily', { LIST_PARAMS => \%LIST_PARAMS });
}



}


#**********************************************************
# admin_report_monthly
#**********************************************************
sub admin_report_monthly {
 
#Payments
require Finance;
Finance->import();
my $payments = Finance->payments($db, $admin, \%conf); 

$ADMIN_REPORT{PAYMENTS}  =  sprintf(" %19s| %9s| %12s|\n", $_DATE, $_COUNT, $_SUM);
$ADMIN_REPORT{PAYMENTS} .= "---------------------------------------------------------\n";

my %LIST_PARAMS = ();
my ($Y, $M, $D)=split(/-/, $YESTERDAY, 3);

$LIST_PARAMS{MONTH}="$Y-$M";
$LIST_PARAMS{PAGE_ROWS}=100000;

$list = $payments->reports( { %LIST_PARAMS } );

foreach my $line (@$list) {
   $ADMIN_REPORT{PAYMENTS} .= sprintf (" %19s| %9s| %12s|\n", 
    "$line->[0]", 
    "$line->[1]", 
    "$line->[2]"
   );
}

$ADMIN_REPORT{PAYMENTS} .= "---------------------------------------------------------\n";
$ADMIN_REPORT{PAYMENTS} .= sprintf("%-14s| %12s|\n%-14s| %12s|\n", 
  $_TOTAL, $payments->{TOTAL},
  $_SUM,   $payments->{SUM});



#Fees
my $fees = Finance->fees($db, $admin, \%conf);

$ADMIN_REPORT{FEES} .= sprintf(" %19s| %9s| %12s|\n", $_DATE, $_COUNT, $_SUM);
$ADMIN_REPORT{FEES} .= "---------------------------------------------------------\n";

$list = $fees->reports( { %LIST_PARAMS } );
foreach my $line (@$list) {
  $ADMIN_REPORT{FEES} .= sprintf (" %19s| %9s| %12s|\n", 
    $line->[0], 
    $line->[1], 
    $line->[2]
   );
    
}

$ADMIN_REPORT{FEES} .= "---------------------------------------------------------\n";
$ADMIN_REPORT{FEES} .= sprintf("%-14s| %12s|\n%-14s| %12s|\n", 
    $_TOTAL, $fees->{TOTAL}, 
    $_SUM,   $fees->{SUM});

#Module report functions
foreach my $function (@reports) {
	$ADMIN_REPORT{MODULES} .= $function->('monthly', { DATE => $DATE,
		                                                 LIST_PARAMS => \%LIST_PARAMS });
}

 

}



#*******************************************************************
# Log rotate
#*******************************************************************
sub logrotate {
	
	
}


#*******************************************************************
# Make backup
# backup()
#*******************************************************************
sub backup {
 #print "$MYSQLDUMP --host=$conf{dbhost} --user=\"$conf{dbuser}\" --password=\"$conf{dbpasswd}\" $conf{dbname} | $GZIP > $conf{BACKUP_DIR}/stats-$DATE.sql.gz";
 my $res = `$MYSQLDUMP -v --host=$conf{dbhost} --user="$conf{dbuser}" --password="$conf{dbpasswd}" $conf{dbname} | $GZIP > $conf{BACKUP_DIR}/stats-$DATE.sql.gz`;
 #print $res;
 #my $message .= "Backup created: $res ($conf{BACKUP_DIR}/stats-$DATE.sql.gz)";
}
