package RT::Action::SendEmail;

use strict;

use warnings;
no warnings qw(redefine);

use base qw(RT::Action);

use RT::EmailParser;
use RT::Interface::Email;
use Email::Address;
our @EMAIL_RECIPIENT_HEADERS = qw(To Cc Bcc);


sub RemoveInappropriateRecipients {
    my $self = shift;

    my %blacklist = ();

    # If there are no recipients, don't try to send the message.
    # If the transaction has content and has the header RT-Squelch-Replies-To

    my $msgid = Encode::decode( "UTF-8", $self->TemplateObj->MIMEObj->head->get('Message-Id') );
    chomp $msgid;

    if ( my $attachment = $self->TransactionObj->Attachments->First ) {

        if ( $attachment->GetHeader('RT-DetectedAutoGenerated') ) {

            # What do we want to do with this? It's probably (?) a bounce
            # caused by one of the watcher addresses being broken.
            # Default ("true") is to redistribute, for historical reasons.

            my $redistribute = RT->Config->Get('RedistributeAutoGeneratedMessages');

            if ( !$redistribute ) {

                # Don't send to any watchers.
                @{ $self->{$_} } = () for (@EMAIL_RECIPIENT_HEADERS);
                $RT::Logger->info( $msgid
                        . " The incoming message was autogenerated. "
                        . "Not redistributing this message based on site configuration."
                );
            } elsif ( $redistribute eq 'privileged' ) {

                # Only send to "privileged" watchers.
                foreach my $type (@EMAIL_RECIPIENT_HEADERS) {
                    foreach my $addr ( @{ $self->{$type} } ) {
                        my $user = RT::User->new(RT->SystemUser);
                        $user->LoadByEmail($addr);
                        $blacklist{ $addr } ||= 'not privileged'
                            unless $user->id && $user->Privileged;
                    }
                }
                $RT::Logger->info( $msgid
                        . " The incoming message was autogenerated. "
                        . "Not redistributing this message to unprivileged users based on site configuration."
                );
            }
        }

        if ( my $squelch = $attachment->GetHeader('RT-Squelch-Replies-To') ) {
            $blacklist{ $_->address } ||= 'squelch:attachment'
                foreach Email::Address->parse( $squelch );
        }
    }

    # Let's grab the SquelchMailTo attributes and push those entries
    # into the blacklisted
    $blacklist{ $_->Content } ||= 'squelch:transaction'
        foreach $self->TransactionObj->SquelchMailTo;
    $blacklist{ $_->Content } ||= 'squelch:ticket'
        foreach $self->TicketObj->SquelchMailTo;

    # canonicalize emails
    foreach my $address ( keys %blacklist ) {
        my $reason = delete $blacklist{ $address };
        $blacklist{ lc $_ } = $reason
            foreach map RT::User->CanonicalizeEmailAddress( $_->address ),
            Email::Address->parse( $address );
    }

    # removed for q2q
    #$self->RecipientFilter(
    #    Callback => sub {
    #        return unless RT::EmailParser->IsRTAddress( $_[0] );
    #        return "$_[0] appears to point to this RT instance. Skipping";
    #    },
    #    All => 1,
    #);

    $self->RecipientFilter(
        Callback => sub {
            return unless $blacklist{ lc $_[0] };
            return "$_[0] is blacklisted $squelch_reasons{ $blacklist{ lc $_[0] } }. Skipping";
        },
    );


    # Cycle through the people we're sending to and pull out anyone that meets any of the callbacks
    for my $type (@EMAIL_RECIPIENT_HEADERS) {
        my @addrs;

      ADDRESS:
        for my $addr ( @{ $self->{$type} } ) {
            for my $filter ( map {$_->{Callback}} @{$self->{RecipientFilter}} ) {
                my $skip = $filter->($addr);
                next unless $skip;
                $RT::Logger->info( "$msgid $skip" );
                next ADDRESS;
            }
            push @addrs, $addr;
        }

      NOSQUELCH_ADDRESS:
        for my $addr ( @{ $self->{NoSquelch}{$type} } ) {
            for my $filter ( map {$_->{Callback}} grep {$_->{All}} @{$self->{RecipientFilter}} ) {
                my $skip = $filter->($addr);
                next unless $skip;
                $RT::Logger->info( "$msgid $skip" );
                next NOSQUELCH_ADDRESS;
            }
            push @addrs, $addr;
        }

        @{ $self->{$type} } = @addrs;
    }
}


1;

