package QueryLogger;
use strict;



sub new {
 ## constructor
my %vars;
my %totals;
my %types;
my %restotals;
my %groups;
my %queries = ();
my %inst = ();
my $class = shift;
my $cid;
my $self = {};
 $self->{itype} = shift || "institution";
# $self->{filename} = shift; # the name of the file to load
 $self->{cid} = shift;
 $self->{vcid} = shift;
 $self->{iid} = shift;
 $self->{mode} = shift || "0"; # if set to something other than 0 the module is in a debug mode
 $self->{types} = \%types;
 $self->{vars} = \%vars;
 $self->{inst} = \%inst;
 $self->{groups} = \%groups;
 $self->{typetotals} = \%totals;
 $self->{restotals} = \%restotals;
 $self->{queries} = \%queries;
 $self->{text} = "";
 bless $self;


return $self;
};


sub DESTROY {
 my $self = shift;
 $self->{itype} = undef;
 $self->{filename} = undef;
 $self->{text} = undef;
 $self->{types} = undef;
 $self->{vcid} = undef;
 $self->{iid} = undef;
 $self->{vars} = undef;
 $self->{inst} = undef;
 $self->{groups} = undef;
 $self->{values} = undef;
 $self->{typetotals} = undef;
 $self->{restotals} = undef;
};

sub add {
 my $self = shift;
 my $ln = shift;
 my $ipt = shift;
 $ln =~ s/[\r\n]//ig;
 $ln =~ s/(\t|\s)+$//ig;
 my @line = split(/\t/,$ln,17);
 #print $line[17];#."\n";
 my %tmp = %{$self->{queries}};
 my %tot = %{$self->{typetotals}};
 my %inst = %{$self->{inst}};
 my %types = %{$self->{types}};
 my %restot = %{$self->{restotals}};
 my %groups = %{$self->{groups}};

# $self->{cid} = $line[9] if $line[9] ne "";
# print $self->{cid};
 next if ($self->{cid} ne $line[9] && $line[9] ne "");
 next if ($self->{vcid} ne $line[11] && $line[11] ne "");
 next if ($self->{iid} ne $line[10] && $line[10] ne "");

 my $resize = $line[14];
 my $groupid = $line[13];
 my $ln_type = $line[15];
 $ln_type .= " $line[16]" if $ln_type =~ /media fetch/i;
 my $loc_ip = $line[5];
 my $ln_user = $line[7];
 my $ln_qs = "$line[15]\t$line[16]";
 my $ln_profile = $line[8];

$ln_qs =~ s/Value\t\t(\d+)\t/Value\t/ig;
$ln_qs =~ s/\tOR\t(\d+)\t/\tOR\t/ig;
$ln_qs =~ s/\tAND\t(\d+)\t/\tAND\t/ig;
#print "\n$ln_qs\n";
my $user;
 if ($self->{itype} =~ /user/i) {
	$user = $ln_user;
 } else {
	$user = $ln_profile;
 };
 $user = $ipt if $ipt ne "";
 ## total query types
 $user =~ s/ /_/ig;
$restot{$user."\t".$ln_qs} = $resize if (!defined $restot{$user."\t".$ln_qs} && $groupid == 1);
$types{$ln_type} = 0 if (!defined $types{$ln_type});


  my $tot_ = "$user\t$ln_type";
  $inst{$user} = 1;


if ($groupid != 1) {
 if (defined $groups{$user."\t".$groupid}) {$groups{$user."\t".$groupid}++;} else {$groups{$user."\t".$groupid} = 1;};
} else {
if (defined $tot{$tot_}) {
 	$tot{$tot_}++;
 } else {$tot{$tot_} = 1;};


 ## total queries
 if (defined $tmp{$user."\t".$ln_qs}) {
 	$tmp{$user."\t".$ln_qs}++;
 } else {$tmp{$user."\t".$ln_qs} = 1;};

};
 $self->{typetotals} = \%tot;
 $self->{groups} = \%groups;
 $self->{restotals} = \%restot;
 $self->{inst} = \%inst;
 $self->{types} = \%types;
 $self->{queries} = \%tmp;

};



sub getCID {
  my $self = shift;
  return $self->{cid};
}




sub getQueries {
  my $self = shift;
  my $user = shift;
  my $gfilter = shift || 0;
  my $rfilter = shift || 0;
  my $pfilter = shift || 0;
  my $ret = "";
#  $user = undef if $user eq "";
  my %tmp;

 my %tmp_;
 while (my ($v1,$v2) = each(%{$self->{queries}})) {
  my ($t1,$t2) = split(/\t/,$v1,2);
  next if ($t1 !~ /^$user$/ && defined $user && $user ne "");
  if (defined $tmp_{$t2}) {$tmp_{$t2} += $v2} else {$tmp_{$t2} = $v2;};
 };
 while (my ($v1,$v2) = each(%tmp_)) {
  next if ($v2 < $pfilter);
    push(@{$tmp{$v2}}, $v1);
 }


$ret .= "<BR><BR><h2>Queries: by Popularity</h2><TABLE border=1><TR><TD><B>Occurrences</B></TD><TD><B>Query</B></TD></TR>\n";
for my $v (sort reversenumerically keys %tmp) {

 for (sort reversenumerically @{$tmp{$v}}) {
   $ret .= "<TR><TD>$v</TD><TD>$_</TD></TR>\n";
 };
};
$ret .= "</TABLE>";
my %restot = %{$self->{restotals}};
my %tot = %{$self->{typetotals}};
my %types = %{$self->{types}};
my %inst = %{$self->{inst}};
my %groups = %{$self->{groups}};

$ret .= "<BR><BR><h2>Queries: by User</h2><TABLE border=1><TR>\n";
$ret .= "<TD><B>User</B></TD><TD><B>".join("</B></TD><TD><B>",sort keys %types);
$ret .= "</B></TD><TD><B>Total</B></TD></TR>";
my $ct_ = 0;
#print join(' ',keys %inst);
for my $ins (sort keys %inst) {
  next if ($ins !~ /^$user/ && $user ne "");
  $ret .= "<TR><TD><B>$ins</B></TD>";
  my $ct =0;
  for my $typ (sort keys %types) {
   my $to_ = $tot{"$ins\t$typ"};
   $ct += $to_;
    $types{$typ} += $to_;
    $to_ = 0 if $to_ eq "";
    $ret .= "<TD>$to_</TD>";
  };
    $ct_ += $ct;
    $ret .= "<TD>$ct</TD></TR>\n";
};
$ret .= "<TD><B>totals</B></TD>";
for (sort keys %types) {
  $ret .= "<TD><B>$types{$_}</B></TD>";
};
$ret .= "<TD><B>$ct_</B></TD>";
$ret .= "</TABLE>";
my %tmp2;
$ret .= "<BR><BR><h2>Queries: by Number of Results</h2><TABLE border=1><TR><TD><B># of results</B></TD><TD><B>Query</B></TD></TR>\n";

 my %tmp2_;
 while (my ($v3,$v4) = each(%{$self->{restotals}})) {
  my ($t3,$t4) = split(/\t/,$v3,2);
  next if ($t3 !~ /^$user/ && defined $user);
  $tmp2_{$t4} = $v4;
 };
 while (my ($v3,$v4) = each(%tmp2_)) {
  next if ($v4 < $rfilter);
    push(@{$tmp2{$v4}}, $v3);
 }



for my $v (sort reversenumerically keys %tmp2) {
 for (sort reversenumerically @{$tmp2{$v}}) {
   $ret .= "<TR><TD>$v</TD><TD>$_</TD></TR>\n";
 };
};

$ret .= "</TABLE>";

$ret .= "<BR><BR><h2>Groups: Group Access</h2><TABLE border=1><TR><TD><B># of requests</B></TD><TD><B>Group</B></TD></TR>";

 my %tmp3;
 my %tmp3_;
 while (my ($v3,$v4) = each(%{$self->{groups}})) {
  my ($t3,$t4) = split(/\t/,$v3,2);
  next if ($t3 !~ /^$user/ && $user ne "");
  if (defined $tmp3{$t4}) {$tmp3{$t4} += $v4} else {$tmp3{$t4} = $v4;};
  #  $tmp3{$t4} = $v4;
 };
 while (my ($v3,$v4) = each(%tmp3)) {
  next if ($v4 < $gfilter);
    push(@{$tmp3_{$v4}}, $v3);
 }

for my $v (sort reversenumerically keys %tmp3_) {
 next if (defined $gfilter && $v < $gfilter);
 for (sort reversenumerically @{$tmp3_{$v}}) {
   $ret .= "<TR><TD>$v</TD><TD>$_</TD></TR>";
 };
};

$ret .= "</TABLE>";

return $ret;
};

sub numerically {$a <=>$b;};

sub reversenumerically {$b <=>$a;};

1;
