#!/usr/bin/perl

use strict;
use warnings;

use FTN::JAM;
use Getopt::Long;
use File::Spec;

my ( $datefrom, $echoarea, %fromnames, %msgsize, %quotecount, $basedir, $dh, 
     $sortoder, $needhelp, $topten );
my $robots = '(Robot)|(UA )|(UKR )|(UKRAINE)|(processor)|(news)|(Business)|(anekdot.ru)|(rulezz)|(Finance)|(Htick)|(HPT)|(Areafix)|(Allfix)|(66NODE)|(File Manager)|(binkd team)|(time[ -]*bot)|(meduza.io)|((faq)|(file)|(news)[ -]*server)|(Brother Fox)|(eku.ru)|(Prikol Bot)|(Admin Sender)|(Security Bot)|(Doctor Bot)|(Family BBS)|(ldm\@weather.cod.edu)|(Roon\'s BBS)|(Hатусяархатуся)|(bot-time)|(R50C NodelistMaker)|(CRBBS Tagline Bot)|(Freezer Master)|(CRBBS Binkd Bot)|(T-Hist)|(2ndchoiceBOT)|(PKTlog)|(Uudecode)|(ArgLog)';

sub usage()
{
    my ( $scr_name );
    if ( $0 =~ /[\\\/]([^\\\/]+)$/ ) {
	$scr_name = $1;
    } else {
	$scr_name = $0;
    }

    print <<ENDUSE;

    Usage: $scr_name [options]
    ~~~~~~
    Options are:
            --help,-h                    - this text.
            --date-from,-d dd.mm.yyyy    - the date from which start to collect
                                           statistics. Optional. Default scan
                                           from the start of the message base.
            --echo-area,-e ECHO.TAG        echo area name to collect statistics.
                                           Optional. Default scan all areas.
            --sort,-s sort_bay             sort oder. Where sort_by is one
                                           of "quote" - sort by quotes number,
                                           "msg" - messages number, "size" - 
                                           total messages size. Optional.
                                           Default sort by messages count.
            --base-dir,-b msg_base_dir     full path to the message base is.
                                           Optional. Default /home/fido/echo.
            --top-ten,-t                   create top ten for all sort oders.
                                           
ENDUSE
exit;
}

GetOptions (	"date-from=s"    => \$datefrom,
		"echo-area=s"    => \$echoarea,
		"sort=s"         => \$sortoder,
		"base-dir=s"     => \$basedir,
		"top-ten"        => \$topten,
		"help"           => \$needhelp
		);


usage() if $needhelp;

$basedir = '/home/fido/mail/echo' unless defined $basedir;
if ( defined( $echoarea ) ) {
	$echoarea =~ s/\*/\.\*/g;
} else { $echoarea = '.*'; }

if (defined($datefrom)){
  if ( $datefrom =~ /(\d\d)[\.\/](\d\d)[\.\/](\d\d\d\d)/ ) {
  	print "Stat from $datefrom\n";
  	$datefrom = $3.$2.$1;
  } else { undef $datefrom; }
}

$sortoder='msg' unless defined $sortoder;

sub listbase($)
{
   my ( $mb ) = @_;
   my ( $handle, %baseheader, $nummsgs, $m_from, $m_to, $m_subj,
	%msgheader, @subfields, $msgtext, $mday,$mon,$year, $msg_date, $m_fromaddr );

	$handle = FTN::JAM::OpenMB($mb);
	if(!$handle) {
#		die "Failed to open $mb";
		print STDERR "Failed to open $mb\n";
		return;
	}

	if (!FTN::JAM::ReadMBHeader($handle,\%baseheader)) {
		die "Failed to read messagebase header of $mb\n";
	}

	if (!FTN::JAM::GetMBSize($handle,\$nummsgs)) {
		die "Failed to get size of messagebase $mb\n";
	}

	for (my $i = $baseheader{BaseMsgNum}; $i < $baseheader{BaseMsgNum}+$nummsgs; $i++) {
		unless ( FTN::JAM::ReadMessage($handle,$i,\%msgheader,\@subfields,\$msgtext)) {
			printf(STDERR "%6s Failed to open message\n",$i);
		}else {
			(undef, $m_from, undef, $m_to, undef, $m_subj, undef, $m_fromaddr ) = @subfields;
			($mday,$mon,$year)=(localtime($msgheader{DateWritten}))[3...5];
			$msg_date = sprintf("%04d%02d%02d",$year+1900,$mon+1,$mday);
			if ( defined( $datefrom ) ){
				next unless $msg_date ge $datefrom;
			}
			next if $m_from =~ /$robots/i;
			$fromnames{$m_from}{msg} = 0 unless defined $fromnames{$m_from}{msg};
			$fromnames{$m_from}{size} = 0 unless defined $fromnames{$m_from}{size};
			$fromnames{$m_from}{quote} = 0 unless defined $fromnames{$m_from}{quote};

			$fromnames{$m_from}{size} += length( $msgtext );
			$fromnames{$m_from}{msg} ++;

			next if $m_to =~ /^All$/i;
			$fromnames{$m_to}{msg} = 0 unless defined( $fromnames{$m_to}{msg} );
			$fromnames{$m_to}{size} = 0 unless defined( $fromnames{$m_to}{size} );
			$fromnames{$m_to}{quote} = 0 unless defined( $fromnames{$m_to}{quote} );
			$fromnames{$m_to}{quote} ++;
		}
	}

	FTN::JAM::CloseMB($handle);
}


unless ( opendir($dh, $basedir) ) {
	print STDERR "Can't open $basedir ($!).\n";
	exit;
}

while( readdir($dh) ) {
	next if $_ eq '.';
	next if $_ eq '..';
	next if $_ =~ /_tmp/i;
	next if $_ =~ /(bad)|(dupe)|(carbon.)mail/i;
	if ( $_ =~ /^($echoarea)\.jdt$/i ) {
		print STDERR "\'$1\'\n";
		listbase( File::Spec->catfile( $basedir, $1 ) );
	}
}
close($dh);

my $l=0;
if ( $topten ) {
    foreach $sortoder ( 'msg', 'size', 'quote' ) {
	print "\nSorted by $sortoder\n";
	print( sprintf( "%-4s %-36s %8s %8s %7s %10s\n", 'N', 'Name', 'Messages', 'Quoted', 'Q.%', 'Total size' ) );
	foreach my $n ( sort { $fromnames{$b}{$sortoder} <=> $fromnames{$a}{$sortoder} } keys %fromnames ) {
	    next if $fromnames{$n}{msg} == 0;
#	    next if ( $sortoder eq 'quote' ) && ( $fromnames{$n}{msg} > $fromnames{$n}{quote} );
	    $l++;
	    print( sprintf( "%-4s %-36s %8s %8s % 7s %11s\n", $l, $n, $fromnames{$n}{msg}, $fromnames{$n}{quote}, sprintf( "%3.2f", ( $fromnames{$n}{quote}/$fromnames{$n}{msg}*100 ) ) . '%', $fromnames{$n}{size} ) );
	    last if $l == 10;
	}
	$l=0;
    }
} else {
  print( sprintf( "%-4s %-36s %8s %8s % 7s %10s\n", 'N', 'Name', 'Messages', 'Quoted', 'Q.%', 'Total size' ) );
  foreach my $n ( sort { $fromnames{$b}{$sortoder} <=> $fromnames{$a}{$sortoder} } keys %fromnames ) {
	next if $fromnames{$n}{msg} == 0;
	next if ( $sortoder eq 'quote' ) && ( $fromnames{$n}{msg} > $fromnames{$n}{quote} );
	$l++;
	print( sprintf( "%-4s %-36s %9s %9s % 7s %10s\n", $l, $n, $fromnames{$n}{msg}, $fromnames{$n}{quote}, sprintf( "%3.2f", ( $fromnames{$n}{quote}/$fromnames{$n}{msg}*100 ) ) . '%', $fromnames{$n}{size} ) );
  }
}
