#!perl -w

use strict;
use POSIX qw(strftime);

use Qpsmtpd::Address;
use Qpsmtpd::Constants;

my $test_email = 'matt@example.com';

sub register_tests {
    my $self = shift;

    $self->register_test('test_invalid_date_range');
    $self->register_test("test_hook_data_post");
}

sub setup_test_headers {
    my $self = shift;

    my $transaction = $self->qp->transaction;
    my $address = Qpsmtpd::Address->new( "<$test_email>" );
    my $header  = Mail::Header->new(Modify => 0, MailFrom => "COERCE");
    my $now    = strftime "%a %b %e %H:%M:%S %Y", localtime time;

    $transaction->sender($address);
    $transaction->header($header);
    $transaction->header->add('From', "<$test_email>");
    $transaction->header->add('Date', $now );
    $transaction->body_write( "test message body " );

    $self->qp->connection->relay_client(0);
    $self->qp->transaction->notes('whitelistsender', 0);
    $self->connection->notes('whitelisthost', 0);
    $self->connection->notes('naughty', 0);
};

sub test_invalid_date_range {
    my $self = shift;

    my $header  = Mail::Header->new(Modify => 0, MailFrom => "COERCE");
    my $transaction = $self->qp->transaction->header($header);

    my $now = strftime "%a %b %e %H:%M:%S %Y", localtime time;
    my $r = $self->invalid_date_range($now);
    ok( ! $r, "valid +") or print "$r\n";

    $self->{_args}{future} = 2;

    my $future_6 = strftime "%a %b %e %H:%M:%S %Y", localtime time + 518400; #6d
    $r = $self->invalid_date_range( $future_6 );
    ok( $r, "too new -" );

    my $future_3 = strftime "%a %b %e %H:%M:%S %Y", localtime time + 259200; #3d
    $r = $self->invalid_date_range( $future_3 );
    ok( $r, "too new -" );

    my $future_1 = strftime "%a %b %e %H:%M:%S %Y", localtime time +  86400; #1d
    $r = $self->invalid_date_range( $future_1 );
    ok( ! $r, "a little new, +" ) or warn "$r\n";


    $self->{_args}{past}   = 2;

    my $past_6   = strftime "%a %b %e %H:%M:%S %Y", localtime time - 518400; #6d
    $r = $self->invalid_date_range( $past_6 );
    ok( $r, "too old -" );

    my $past_3   = strftime "%a %b %e %H:%M:%S %Y", localtime time - 259200; #3d
    $r = $self->invalid_date_range( $past_3 );
    ok( $r, "too old -" );

    my $past_1   = strftime "%a %b %e %H:%M:%S %Y", localtime time -  86400; #1d
    $r = $self->invalid_date_range( $past_1 );
    ok( ! $r, "a little old +" );
};

sub test_hook_data_post {
    my $self = shift;

    $self->{_args}{reject} = 1;
    my $reject = $self->{_args}{reject_type};
    my $deny   = $reject =~ /^temp|soft$/i ? DENYSOFT : DENY;

    $self->setup_test_headers();
    my $transaction = $self->qp->transaction;

    my ($code, $mess) = $self->hook_data_post( $transaction );
    $mess ||= '';  # avoid undef warning
    cmp_ok( DECLINED, '==', $code, "okay $code, $mess" );

    $transaction->header->delete('Date');
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( $code, '==', $deny, "missing date ( $code, $mess )" );

    my $now    = strftime "%a %b %e %H:%M:%S %Y", localtime time;
    $transaction->header->add('Date', $now );
    $transaction->header->delete('From');
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( $deny, '==', $code, "missing from ( $code, $mess )" );
    $transaction->header->add('From', "<$test_email>");

    $self->{_args}{future} = 5;
    my $future = strftime "%a %b %e %H:%M:%S %Y", localtime time + 518400; #6d
    $transaction->header->replace('Date', $future );
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( $deny, '==', $code, "too new ( $code, $mess )" );

    $self->{_args}{past} = 5;
    my $past = strftime "%a %b %e %H:%M:%S %Y", localtime time - 518400; #6d
    $transaction->header->replace('Date', $past );
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( $deny, '==', $code, "too old ( $code, $mess )" );

    $self->{_args}{reject_type} = 'temp';
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( DENYSOFT, '==', $code, "defer, not deny ( $code, $mess )" );

    $self->{_args}{reject_type} = 'perm';
    ($code, $mess) = $self->hook_data_post( $transaction );
    cmp_ok( DENY, '==', $code, "deny ( $code, $mess )" );
};