#!/usr/bin/perl
#
# $Id$
#

use strict;
use Getopt::Std;
use IO::Socket;
use IO::Socket::SSL;
use Mail::IMAPClient;
use File::Temp qw/tempfile/;
use Carp;

my %opts;
getopts('DScdfhlsvF:H:i:u:p:P:',\%opts);

help_exit() if $opts{h};
help_exit() if not ($opts{u} and $opts{p});

my $DEBUG       = $opts{D};
my $subfolders  = $opts{S};                     # only subfolders
my $count       = $opts{c};
my $delete      = $opts{d};                     # delete mail on server
my $user        = $opts{u};
my $with_folders = $opts{f};
my $folder      = $opts{F};
my $ssl         = $opts{s};
my $pass        = $opts{p};
my $inbox       = $opts{i};                     # load mails to inbox directory 
my $host        = $opts{H}  || 'localhost';
my $verbose     = $opts{v};
my $port_arg    = $opts{P};

$with_folders = 1 if $subfolders;

# port_arg with predence
my $port = $port_arg ne ''  ? $port_arg
         : $ssl             ? 993
         :                    143
         ;

my $imap = Mail::IMAPClient->new();
$imap->Server($host);
$imap->Port($port);
$imap->Ssl($ssl);
$imap->Uid(1);
$imap->Debug($DEBUG) if $DEBUG;

$imap->connect();

$imap->User($user);
$imap->Password($pass);

$imap->login();

my $sepChar = $imap->separator();

if ($imap->Authenticated()) {
    print "Login for user $user successful.\n" if $verbose;
}

if ($folder) {
    $folder = 'INBOX'.$imap->separator.$folder;
}
else {
    $folder = 'INBOX';
}

if (!$subfolders) {
    $imap->select($folder);
    if ($verbose) {
        print "$folder";
        print ': ',$imap->message_count,' messages' if $count;
        print "\n";
    }
    save_mails($imap,$inbox,$delete) if $inbox;
    $imap->close();
}

if ($with_folders) {
    print "* Subfolders:\n" if $verbose;
    my @folders = $imap->folders() or die "Cannot list folders: $@\n";
    foreach my $subfolder (@folders) {
        $subfolder =~ s/\s+$//;
        if ($subfolder =~ /^INBOX$/) {
            next;
        }
        $imap->select($subfolder);
        #$subfolder =~ s/^INBOX$sepChar?(.+)$/$1/;
        if ($verbose) {
            print "  $subfolder";
            print ': ',$imap->message_count,' messages' if $count;
            print "\n";
        }
        save_mails($imap,$inbox,$delete) if $inbox;
        $imap->close();
    }
}


my @raw_out = $imap->list() or die "Could not list: $@\n";
$imap->logout() or die "Could not logout: $@\n";

### SUBS ###
#

### save_mails
sub save_mails
{
    my ($imap,$inbox,$delete) = @_;

    foreach my $msg_id ($imap->messages()) {
        my ($fh,$tmpfile) = tempfile($msg_id.'_XXXXXXXXXXXX',
                                     DIR => $inbox,
                                     SUFFIX => '');
        if (defined $fh) {
            $imap->message_to_file($fh,$msg_id);
            if (! $fh->close) {
                croak "Cannot write tempfile $tmpfile: $!\n";
            }
            my $emlfile = $tmpfile.'.eml';
            link $tmpfile, $emlfile;
            unlink $tmpfile;
            $imap->delete_message($msg_id) if $delete;
        }
    }
}

### help_exit
sub help_exit
{
    print "Aufruf: benno-imap [-D] -u <user> -p <pass> [-H <host>] [-P <port>] [-s] [-v]\n";
    print "        [-c] [-F <folder>] [-f][-S] [-i <inbox_dir>] [-d]\n";
    print "\n";
    print "  -u <username>  imap username\n";
    print "  -p <password>  imap password\n";
    print "  -H <host>      imap host (default localhost)\n";
    print "  -P <port>      imap port (default 143)\n";
    print "  -F <folder>    select folder <folder> after login (default INBOX)\n";
    print "  -i <inbox_dir> save mails in <inbox_dir>\n";
    print "  -f             with subfolders\n";
    print "  -S             only subfolders (implies -f)\n";
    print "  -s             imaps (default port 993)\n";
    print "  -c             count messages in folder\n";
    print "  -d             delete mails on server after stored in inbox\n";
    print "  -v             verbose\n";
    exit 1;
}


