#!/usr/bin/perl -w

use 5.006_000;
use Cwd;
use File::Spec;
use Fcntl qw/:seek/;
use strict;

my $mh_root = $ARGV[0] || '.';
my $mbox_dest = $ARGV[1] || File::Spec->catdir($ENV{'HOME'}, 'mail');

sub parse_mail
{
    my ($fh) = @_;
    my ($envsender, $date);

    my $old_pos = tell $fh;
    seek $fh, 0, SEEK_SET; 

    while(<$fh>) {
        if(!defined($envsender)) {
            if(/^Return-Path:\s+<?(.*?)>?\s*$/ || /^From:\s+.*?<.*?>/
               || /^From:\s+(.*)$/)
            {
                $envsender = $1;
            }
        }

        if(!defined($date)) {
            if(/^Date:\s+(.*)\s*$/) {
                $date = $1;
            }
        }

        last if(defined($envsender) && defined($date));
    }

    $envsender = '-' unless(defined($envsender));
    $date = 'Unknown Date' unless(defined($date));

    seek $fh, $old_pos, SEEK_SET;

    return ($envsender, $date);
}

sub read_mh_dir
{
    my ($dir, $folder_path) = @_;

    print "read_mh_dir($dir, $folder_path)\n";

    my $oldpwd = cwd;
    chdir $dir and do {
        my $mbox_file = File::Spec->catfile($mbox_dest, $folder_path);
        my $mbox_dir = File::Spec->catdir($mbox_dest, $folder_path . '.sbd');

        my $mbox_fh = undef;
        open($mbox_fh, ">>$mbox_file") and do {
            opendir(DIR, '.') and do {
                foreach my $name (readdir DIR) {
                    next if($name =~ /^\./);
                    if(-d $name) {
                        if(! -d $mbox_dir) {
                            mkdir($mbox_dir, 0700) or do {
                                warn "can't mkdir $mbox_dir: $!";
                                next;
                            };
                        }

                        my $newpath = File::Spec->catdir($folder_path . '.sbd', $name);
                        read_mh_dir($name, $newpath);
                    } elsif(-f $name) {
                        open(MAIL, "<$name") or next;

                        # if the first line is indeed a 'From ' header, skip
                        # generating our own
                        my $firstline = <MAIL>;
                        if($firstline =~ /^From\s+.+$/) {
                            print { $mbox_fh } $firstline;
                        } else {
                            my ($evsender, $date) = parse_mail *MAIL;
                            print { $mbox_fh } "From $evsender $date\n";
                        }

                        while(<MAIL>) {
                            s/^From />From /;
                            print { $mbox_fh } $_;
                        }
                        close MAIL;

                        print { $mbox_fh } "\n";
                    }
                }

                closedir DIR;
                1;
            } or warn "can't open $dir: $!";

            close $mbox_fh;
            unlink $mbox_file if((stat($mbox_file))[7] == 0);
            1;
        } or warn "can't append to $mbox_file: $!";

        print "chdir($oldpwd)\n";
        chdir $oldpwd;
        1;
    } or warn "can't chdir to $dir: $!";
}

chdir($mh_root) or die "can't chdir to $mh_root: $!";
opendir(MH_ROOT, '.') or die "can't open $mh_root: $!";
foreach (readdir MH_ROOT) {
    next if(/^\./);
    read_mh_dir($_, $_);
}
closedir(MH_ROOT);
