#!/usr/bin/perl -w
# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
#
# Mail delivery agent for public-inbox, run from your MTA upon mail delivery
my $help = <<EOF;
usage: public-inbox-mda [OPTIONS] </path/to/RFC2822_message

options:

  --no-precheck  skip internal checks for spam messages

See public-inbox-mda(1) man page for full documentation.
EOF
use strict;
use Getopt::Long qw(:config gnu_getopt no_ignore_case auto_abbrev);
my ($ems, $emm, $show_help);
my $precheck = 1;
use PublicInbox::Import;
local $PublicInbox::Import::DROP_UNIQUE_UNSUB; # does this need a CLI switch?
GetOptions('precheck!' => \$precheck, 'help|h' => \$show_help) or
	do { print STDERR $help; exit 1 };
if ($show_help) {
	print $help;
	exit;
}

my $do_exit = sub {
	my ($code) = shift;
	$emm = $ems = undef; # trigger DESTROY
	exit $code;
};

use PublicInbox::Eml;
use PublicInbox::MDA;
use PublicInbox::Config;
use PublicInbox::Emergency;
use PublicInbox::Filter::Base;
use PublicInbox::InboxWritable;
use PublicInbox::Spamcheck;

# n.b.: Hopefully we can set up the emergency path without bailing due to
# user error, we really want to set up the emergency destination ASAP
# in case there's bugs in our code or user error.
my $emergency = $ENV{PI_EMERGENCY} || "$ENV{HOME}/.public-inbox/emergency/";
$ems = PublicInbox::Emergency->new($emergency);
my $str = PublicInbox::IO::read_all \*STDIN;
PublicInbox::Eml::strip_from($str);
$ems->prepare(\$str);
my $eml = PublicInbox::Eml->new(\$str);
my $cfg = PublicInbox::Config->new;
my $key = 'publicinboxmda.spamcheck';
my $default = 'PublicInbox::Spamcheck::Spamc';
my $spamc = PublicInbox::Spamcheck::get($cfg, $key, $default);
my $dests = [];
PublicInbox::Import::load_config($cfg, $do_exit);

my $recipient = $ENV{ORIGINAL_RECIPIENT};
if (defined $recipient) {
	my $ibx = $cfg->lookup($recipient); # first check
	push @$dests, $ibx if $ibx;
}
if (!scalar(@$dests)) {
	$dests = PublicInbox::MDA->inboxes_for_list_id($cfg, $eml);
	if (!scalar(@$dests) && !defined($recipient)) {
		warn "ORIGINAL_RECIPIENT not defined in ENV\n";
		$do_exit->(67); # EX_NOUSER
	}
	scalar(@$dests) or $do_exit->(67); # EX_NOUSER 5.1.1 user unknown
}

my $err;
@$dests = grep {
	my $ibx = PublicInbox::InboxWritable->new($_);
	$ibx->{indexlevel} = $ibx->detect_indexlevel;
	eval { $ibx->assert_usable_dir };
	if ($@) {
		warn $@;
		$err = 1;
		0;
	# pre-check, MDA has stricter rules than an importer might;
	} elsif ($precheck) {
		!!PublicInbox::MDA->precheck($eml, $ibx->{address});
	} else {
		1;
	}
} @$dests;

$do_exit->(67) if $err && scalar(@$dests) == 0;

$eml = undef;
my $spam_ok;
if ($spamc) {
	$str = '';
	$spam_ok = $spamc->spamcheck($ems->fh, \$str);
	# update the emergency dump with the new message:
	$emm = PublicInbox::Emergency->new($emergency);
	$emm->prepare(\$str);
	$ems = $ems->abort;
} else { # no spam checking configured:
	$spam_ok = 1;
	$emm = $ems;
	my $fh = $emm->fh;
	read($fh, $str, -s $fh);
}
$do_exit->(0) unless $spam_ok;

# -mda defaults to the strict base filter which we won't use anywhere else
sub mda_filter_adjust ($) {
	my ($ibx) = @_;
	my $fcfg = $ibx->{filter} || '';
	if ($fcfg eq '') {
		$ibx->{filter} = 'PublicInbox::Filter::Base';
	} elsif ($fcfg eq 'scrub') { # legacy alias, undocumented, remove?
		$ibx->{filter} = 'PublicInbox::Filter::Mirror';
	}
}

my @rejects;
for my $ibx (@$dests) {
	mda_filter_adjust($ibx);
	my $filter = $ibx->filter;
	my $mime = PublicInbox::Eml->new($str);
	my $ret = $filter->delivery($mime);
	if (ref($ret) && ($ret->isa('PublicInbox::Eml') ||
			$ret->isa('Email::MIME'))) { # filter altered message
		$mime = $ret;
	} elsif ($ret == PublicInbox::Filter::Base::IGNORE) {
		next; # nothing, keep looping
	} elsif ($ret == PublicInbox::Filter::Base::REJECT) {
		push @rejects, $filter->err;
		next;
	}

	PublicInbox::MDA->set_list_headers($mime, $ibx);
	my $im = $ibx->importer(0);
	if (defined $im->add($mime)) {
		# ->abort is idempotent, no emergency if a single
		# destination succeeds
		$emm->abort;
	} else { # v1-only
		my $mid = $mime->header_raw('Message-ID');
		# this message is similar to what ssoma-mda shows:
		print STDERR "CONFLICT: Message-ID: $mid exists\n";
	}
	$im->done;
}

if (scalar(@rejects) && scalar(@rejects) == scalar(@$dests)) {
	$! = 65; # EX_DATAERR 5.6.0 data format error
	die join("\n", @rejects, '');
}

$do_exit->(0);
