#!/usr/bin/perl -w
#
# <@LICENSE>
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to you under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at:
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# </@LICENSE>

my $argcffile = shift @ARGV;
my $scoreset = shift @ARGV;
$scoreset = 0 if ( !defined $scoreset );

my %freq_spam = ();
my %freq_nonspam = ();

my $num_spam;
my $num_nonspam;
my $num_total;

my %mutable_tests = ();
my %ranking = ();
my %soratio = ();
my %is_nice = ();

if (!defined $argcffile) { $argcffile = "../rules"; }

my $tmpf = "./tmp/rules$$.pl";
system "../build/parse-rules-for-masses ".
      "-d \"$argcffile\" -s $scoreset -o $tmpf" and die;
require $tmpf;
unlink $tmpf;

while (<>) {
  /^\s*([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+\S+\s+(.+)\s*$/ or next;

  my $overall = $1+0;
  my $spam = $2+0;
  my $nonspam = $3+0;
  my $soratio = $4+0;
  my $ranking = $5+0;
  my $test = $6;

  if ($test eq '(all messages)') {
    $num_spam = $spam;
    $num_nonspam = $nonspam;
    $num_total = $spam+$nonspam;
    next;
  }
  next if ($test eq '(all messages as %)');

  if (!defined ($rules{$test})) {
    warn "$test: rule no longer exists; ignoring\n";
    next;
  }

  $freq{$test} = $overall;
  $freq_spam{$test} = $spam;
  $freq_nonspam{$test} = $nonspam;

  my $tflags = $rules{$test}->{tflags}; $tflags ||= '';

  $mutable_tests{$test} = 1;

  # "userconf" rules, or "net" rules in set 0/2, or "learn" rules
  # in set 1/3, are nonmutable.
  if ($tflags =~ /\buserconf\b/) {
    print "$test: immutable due to 'userconf'\n";
    $mutable_tests{$test} = 0;
  }
  elsif ( ($scoreset & 1) == 0 && $tflags =~ /\bnet\b/ ) {
    print "$test: immutable due to 'net'\n";
    $mutable_tests{$test} = 0;
  }
  elsif ( ($scoreset & 2) == 0 && $tflags =~ /\blearn\b/ ) {
    print "$test: immutable due to 'learn'\n";
    $mutable_tests{$test} = 0;
  }
  elsif (!$rules{$test}->{mutable}) {
    # rules read from the non-mutable section
    print "$test: immutable according to parse-rules\n";
    $mutable_tests{$test} = 0;
  }
  elsif ($rules{$test}->{score} == 0) {
    # this causes trouble, since rewrite-with-new-scores has a tendency
    # to "simplify" scores down to 0.  comment, since real zero-scored rules
    # that were scored zero when the mass-check ran, will also have no hits
    # and the 'less than 0.01%' case below takes care of that.
    # print "$test: immutable since score is 0\n";
    # $mutable_tests{$test} = 0;
  }

  if ($tflags =~ m/\bnice\b/i) {
    $is_nice{$test} = 1;
  } else {
    $is_nice{$test} = 0;
  }

  # less than 0.01% of messages were hit: force these rules to 0.0
  if ($overall < 0.01) {
    print "$test: zeroing rule and marking immutable, due to low hitrate\n";
    $mutable_tests{$test} = 0;
    $soratio{$test} = 0.5;
    $ranking{$test} = 0.0;
    $rules{$test}->{score} = 0; # tvd - disable these rules automagically

  } else {
    $soratio{$test} = $soratio;
    $ranking{$test} = $ranking;
  }
}

if ( ! mkdir "tmp", 0755 ) {
  warn "Couldn't create tmp directory!: $!\n";
}

open (OUT, ">tmp/ranges.data");
foreach my $test (sort { $ranking{$b} <=> $ranking{$a} } keys %freq) {
  if (!defined ($rules{$test})) {
    warn "$test: rule not found! forcing score to 0";
    print OUT ("0 0 0 $test\n");
    next;
  }

  my $overall = $freq{$test};
  my $spam = $freq_spam{$test};
  my $nonspam = $freq_nonspam{$test};
  my $soratio = $soratio{$test};
  my $ranking = $ranking{$test};
  my $mutable = $mutable_tests{$test};

  # non-mutable, or score of 0 -- lock down to current score.
  if (!$mutable) {
    printf OUT ("%3.3f %3.3f 0 $test\n",
                              $rules{$test}->{score},
                              $rules{$test}->{score});
    next;
  }

  my ($lo, $hi);
  if ($is_nice{$test}) {
    $hi = 0;
    $lo = $ranking{$test} * -4.5;
  }
  else {
    $lo = 0;
    $hi = $ranking{$test} * 4.5;
  }

  printf OUT ("%3.1f %3.1f $mutable $test\n", $lo, $hi);
}
close OUT;
exit;


