#!/usr/bin/perl
use strict;
use warnings;

use utf8;
use IO::All;
use Try::Tiny;
use Courriel::Builder;
use Email::Address;
use Email::Sender::Simple 'sendmail';
use Email::Sender::Transport::SMTP ();
use Getopt::Long::Descriptive;

sub get_subject {
    my $body = shift;
    $body =~ /<title>(.+)<\/title>/ and return $1;
    return;
}

my ( $opt, $usage ) = describe_options(
    '%c %o',
    [ 'input-file|i=s', 'Formatted input file'               ],
    [ 'list-file|l=s',  'Email list file'                    ],
    [ 'attach|a=s@',    'Attachments (may be repeated)'      ],
    [ 'subject|s=s',    'Subject'                            ],
    [ 'to|t=s@',        'Email to send to (may be repeated)' ],
    [],
    [ 'verbose|v', 'Verbosity'              ],
    [ 'help',      'Usage message and exit' ],
);

$opt->help       and print $usage->text and exit;
$opt->input_file or  print $usage->text and exit;

if ( ! $opt->list_file && ! $opt->to ) {
    print "Error: must provide a list file or an address\n";
    print $usage->text;
    exit;
}

if ( $opt->list_file && $opt->to ) {
    print "Error: can't provide both a list file and an addres\n";
    print $usage->text;
    exit;
}

my $body    = io( $opt->input_file )->utf8->slurp;
my $from    = Email::Address->new( 'Israel Society for the Abolition of Vivisection' => 'isav@isav.org.il' );
my @addrs   = $opt->to ?
    @{ $opt->to }      :
    map { chomp; $_ } io( $opt->list_file )->utf8->slurp;

my $total   = scalar @addrs;
my $subject = $opt->subject || get_subject($body)
    or die "No subject!\n";

my $current = 0;
foreach my $addr (@addrs) {
    my @to = Email::Address->parse($addr) or die "Failed parsing $addr\n";
    @to == 1 or die "Found more than one for $addr\n";
    my $to = shift @to;
    printf "-> $to (%d/$total)\n", $current++ + 1;

    my $html_body   = '';
    my @html_attach = ();
    if ( $opt->attach ) {
        my @img_attach = ();
        foreach my $attach ( @{ $opt->attach } ) {
            if ( $attach !~ /\.(jpe?g|png)$/ ) {
                push @html_attach, $attach;
                next;
            }

            push @img_attach, $attach;
        }

        $html_body = html_body(
            $body,
            map { attach($_) } @img_attach,
        );
    } else {
        $html_body = html_body($body);
    }

    my $email = build_email(
        subject($subject),
        from($from),
        to($addr),
        $html_body,
        map { attach($_) } @html_attach,
    );

    try {
        sendmail(
            $email,
            { transport => Email::Sender::Transport::SMTP->new() }
        );
    } catch {
        warn "sending failed: $_";
    };
}

print "Done\n";

