use Getopt::Long;

main();

sub main {
  my ($help, $log, $format, $out) = ();
  $result = GetOptions ('help|h' => \$help,
                        'log|l=s' => \$log,
                        'format|f=s' => \$format,
                        'out|o=s' => \$out);
  $format = 'html' unless ($format);
  if ($help || !$log
      || ($format ne 'html' && $format ne 'csv')
     )
  {
    print 'usage: ',$0," -l <log file> [-f (html|csv)] [-o <destination file>]\n";
    print '       ',$0," --log <log file> [-format (html|csv)] [--out <destination file>]\n";
  } else {
    parse_log($log);
    if ($out)
    {
      open(STDOUT, ">$out") || die 'Unable to write to file: ',$out,"\n";
    }
    if ($format eq 'csv')
    {
      dump_csv();
    } else {
      dump_html();
    }
  }
}

%attributes = ();

sub increment_index ($$)
{
  my ($attribute, $index) = @_;
  my $entry = $attributes{$attribute};
  if ($entry)
  { 
    ${$entry}{$index}++;
  } else {
    $entry = { $index, 1 };
    $attributes{$attribute} = $entry;
  }
}

sub dump_html 
{
  my %format;
  $format{'header'} = << "EOF";
<html>
 <head>
 </head>
 <body>
  <table>
EOF
  $format{'key-header'} = << "EOF";
   <tr>
    <th>Attributes</th>
EOF
  $format{'pre-key'} = '    <th>';
  $format{'post-key'} = "</th>\n";
  $format{'key-footer'} = << "EOF";
   </tr>
EOF
  $format{'count-header'} = << "EOF";
   <tr>
EOF
  $format{'pre-count'} = '    <th>';
  $format{'post-count'} = "</th>\n";
  $format{'count-footer'} = << "EOF";
   </tr>
EOF
  $format{'footer'} = << "EOF";
  </table>
 </body>
</html>
EOF
  $format{'precount'}='   <th>';
  $format{'postcount'}='</th>',"\n";
  dump_results(%format);
}

sub dump_csv
{
  my %format;
  $format{'pre-key'} = ',';
  $format{'key-footer'} = "\n";
  $format{'post-count'} = ',';
  $format{'count-footer'} = "\n";
  dump_results(%format);
}

sub dump_results (%)
{
  my (%format) = @_;
  @indexes = ('pres', 'eq', 'approx', 'subinitial', 'subany', 'subfinal', 'substr'); 
  print $format{'header'};
  print $format{'key-header'};
  foreach $index (@indexes)
  {
    print $format{'pre-key'},$index,$format{'post-key'};
  }
  print $format{'key-footer'};
  foreach $attr (sort(keys(%attributes)))
  {
    print $format{'count-header'};
    print $format{'pre-count'},$attr,$format{'post-count'};
    foreach $index (@indexes)
    {
      print $format{'pre-count'},(${$attributes{$attr}}{$index} or '0'),$format{'post-count'};
    }
    print $format{'count-footer'};
  }
  print $format{'footer'};
}

sub parse_log ($)
{
  my $file = shift;
  open(LOG, "<$file") || die 'Unable to read file: ',$file,"\n";

  my $line;
  while ($line = <LOG>) {
    if ($line=~/ SRCH /)
    {
      my ($filter) = $line=~/filter="(.*?)"/;
      foreach $filter (split(/\(/,$filter))
      {
        if ($filter=~/=/)
        {
          $filter=~s/\)*$//;
          parse_filter($filter) 
        }
      }
    }
  }
}

sub parse_filter ($) {
  my $filter = shift;

  return if ($filter eq '?=undefined' );

  my ($attr, $filtertype, $value) = $filter=~/([[:alnum:]-;]+)(.?=)(.*)/;

  return if ($filtertype=~/[><:]=/);

  if ($filtertype eq '~=')
  {
    increment_index($attr, 'approx');
  }
  elsif ($filtertype eq '=')
  {
    if ($value=~/^\*$/)
    {
      increment_index($attr, 'pres');
    }
    elsif ($value=~/[^*]+\*[^*]+/)
    {
      increment_index($attr, 'substr');
    }
    elsif ($value=~/^\*.+\*$/)
    {
      increment_index($attr, 'subany');
    }
    elsif ($value=~/.+\*$/)
    {
      increment_index($attr, 'subfinal');
    }
    elsif ($value=~/^\*.+/)
    {
      increment_index($attr, 'subinitial');
    }
    else
    {
      increment_index($attr, 'eq');
    }
  }
  else
  {
    print STDERR 'unknown filter: ',$filter,"\n";
  }
}
