package LinuxStableQueue;

use strict;
use warnings;
use Config::Simple;
use Cwd ();
use File::Path ();
use MIME::Words ();
use POSIX ();

BEGIN {
    use Exporter ();

    our (@ISA, @EXPORT_OK);

    @ISA = qw(Exporter);
    @EXPORT_OK = qw($STABLE_QUEUES %STABLE_GIT $UPSTREAM_GIT $MAIL_FROM
		    $MAIL_ANNOUNCE_TO $MAIL_ANNOUNCE_CC $MAIL_REVIEW_TO
		    $MAIL_REVIEW_COVER_CC $MAIL_REVIEW_CC $STABLE_RC_URL
	            &base_version &last_update &next_update &get_queue
		    &get_git &common_mail_header
		    &mime_entity_to_mbox &print_signature &parse_mailbox_addr
		    &mailbox_addr_to_addr_spec &make_mailbox_addr
		    &parse_mailbox_list &quilt_dir_from_git_dir);
}

our ($STABLE_QUEUES, %STABLE_GIT, $UPSTREAM_GIT, $MAIL_FROM,
     $MAIL_ANNOUNCE_TO, $MAIL_ANNOUNCE_CC, $MAIL_REVIEW_TO,
     $MAIL_REVIEW_COVER_CC, $MAIL_REVIEW_CC);

# Config::Simple does a reasonably good job of parsing shell variable
# assignments.
my $config = new Config::Simple(
    filename => "${ENV{HOME}}/.config/linux-stable-queue",
    syntax => 'simple');
my $vars = $config->vars();

# Convert each known config variable to a module-level variable,
# except for STABLE_GIT_* which we convert to a single variable.
for my $key (keys %$vars) {
    if ($key =~ /^default\.(STABLE_QUEUES|UPSTREAM_GIT|MAIL_(?:FROM|ANNOUNCE_(?:TO|CC)|REVIEW_(?:TO|COVER_CC|CC))|STABLE_RC_URL)$/) {
	no strict 'refs';
	${$1} = $vars->{$key};
    } elsif ($key =~ /^default\.STABLE_GIT_([\d_]+)$/) {
	my $base = $1;
	$base =~ s/_/./g;
	$STABLE_GIT{$base} = $vars->{$key};
    }
}

# Get base version, i.e. the Linus stable release that a version is based on
sub base_version {
    my ($ver) = @_;
    $ver =~ s/-rc.*$//;
    $ver =~ s/^((?:2\.6|[3-9]|..)\..*)\..*/$1/;
    return $ver;
}

sub add_update {
    my ($ver, $delta) = @_;
    my ($base, $update);
    $base = base_version($ver);
    $update = $ver;
    $update =~ s/^\Q$base.\E// or $update = 0;;
    $update += $delta;
    return ($update == 0) ? $base : "$base.$update";
}

# Get last stable update version (or Linus stable release, for .1)
sub last_update {
    my ($ver) = @_;
    return add_update($ver, -1);
}

# Get next stable update version
sub next_update {
    my ($ver) = @_;
    return add_update($ver, 1);
}

# Get patch queue directory for a given base version
sub get_queue {
    my ($base) = @_;
    my $queue = "$STABLE_QUEUES/queue-$base";
    File::Path::make_path $queue or die "$!";
    return $queue;
}

# Get git repo directory for a given base version
sub get_git {
    my ($base) = @_;
    return $STABLE_GIT{$base};
}

# We want messages to display in the right order if sorted by either
# Subject or Date.  The Date field only has 1 second resolution, so
# add 1 second for each message.
my $mail_time;
sub next_mail_time {
    if ($mail_time) {
	++$mail_time;
    } else {
	$mail_time = time();
    }
    return $mail_time;
}

# Return common mail header fields
sub common_mail_header {
    # XXX Surely there are common utilities for this?
    my $date = POSIX::strftime('%a, %d %b %Y %H:%M:%S %z',
			       localtime(next_mail_time()));
    my $domain = $MAIL_FROM;
    $domain =~ s/>?\s*$//;
    $domain =~ s/^.*\@//;
    my $mid = '<lsq.' . time() . '.' . int(rand(1e9)) . "\@$domain>";
    return (Date => $date,
	    'Message-Id' => $mid,
	    'X-Mailer' => 'LinuxStableQueue (scripts by bwh)',
	    'X-Patchwork-Hint' => 'ignore');
}

sub mime_entity_to_mbox {
    my ($entity, $mbox_fh) = @_;

    for my $part ($entity->parts ? $entity->parts : ($entity)) {
	if ($part->as_string =~ /^From /m) {
	    # We have to use QP and escape this later.  The as_string
	    # method will take care of escaping everything else as
	    # needed for QP.
	    $part->head->replace('Content-Transfer-Encoding',
				 'quoted-printable');
	}
    }

    # Escape 'From ' within the message and ensure are at least two '\n'
    # before the 'From ' of the next message
    my $text = $entity->as_string;
    $text =~ s/^From /=46rom /gm;
    while ($text !~ /\n\n$/) {
	$text .= "\n";
    }

    # The address here will become the SMTP sender when using
    # formail + sendmail.  For now, copy the From address.  The date
    # is irrelevant though.
    my $sender = mailbox_addr_to_addr_spec($entity->head->get('From'));
    $mbox_fh->print("From $sender Mon Mar 25 00:00:00 2013\n");
    $mbox_fh->print($text);
}

sub print_signature {
    my ($out_fh) = @_;
    my $sig_fh = new FileHandle("${ENV{HOME}}/.signature", 'r');
    if (defined($sig_fh)) {
	print $out_fh "\n-- \n";
	while (<$sig_fh>) {
	    print $out_fh $_;
	}
	close($sig_fh);
    }
}

# Split mailbox address into name (if present) and addr-spec.
# Don't bother handling comments or rejecting all illegal characters.
sub parse_mailbox_addr {
    my ($mailbox) = @_;
    my ($name, $addr_spec);
    if ($mailbox =~ /^\s*((?:[^<]|\\.)*)\s*<([^<>]+)>\s*$/) {
	($name, $addr_spec) = ($1, $2);
	$name =~ s/\s*$//;
    } else {
	$addr_spec = $mailbox;
    }
    return ($name, $addr_spec);
}

sub mailbox_addr_to_addr_spec {
    return (parse_mailbox_addr(@_))[1];
}

# Make mailbox address from name (may be undef) and addr-spec.
sub make_mailbox_addr {
    my ($name, $addr_spec) = @_;
    if (!defined($name)) {
	return $addr_spec;
    } else {
	# Quote and MIMEify name as necessary
	if ($name !~ /^".*"$/) {
	    $name = "\"$name\"";
	}
	$name = MIME::Words::encode_mimewords($name, Charset => 'UTF-8');
	return "$name <$addr_spec>";
    }
}

# Split mailbox list into mailbox addresses.
# List is comma-separated, but addresses may also contain quoted or
# escaped commas.
sub parse_mailbox_list {
    my ($list) = @_;
    my (@mailboxes);
    while ($list =~ /\G((?:[^,\\\"]|\\.|"(?:[^,\\\"]|\\.)*")+),?/g) {
	push @mailboxes, $1;
    }
    return @mailboxes;
}

sub quilt_dir_from_git_dir {
    my ($git_dir) = @_;
    $git_dir = Cwd::abs_path($git_dir);
    for my $base (keys %STABLE_GIT) {
	if ($git_dir eq Cwd::abs_path($STABLE_GIT{$base})) {
	    return "$STABLE_QUEUES/queue-$base";
	}
    }
    return undef;
}

1;
