#! /usr/bin/env perl

use strict;
use warnings;
use Fcntl qw(:DEFAULT :flock);
use Term::ReadLine;
use File::Copy;
use locale;

my ($action, $filename)=@ARGV;
my $labelfilename=$ENV{HOME} . "/.muttXlabels";
die "$filename not readable" unless -r $filename;
#die "$labelfilename not readable. Create it." unless -r $labelfilename;
die "strange filename" unless $filename=~m{([^/]*)$};
my $basefilename=$1;
my $tmpfilename="/tmp/editlabels-$basefilename.$$";
my $history="$ENV{HOME}/.editlabelhistory";
my $maxhistory=100; #how many labels to remember in history

sysopen LABELS, $labelfilename, O_RDWR|O_CREAT or die "Can't open $labelfilename $!"; 
flock(LABELS, LOCK_SH) 
    or die "Can't lock $labelfilename $!"; #puts a shared lock
chomp(my @labels=<LABELS>);
my %labels;
foreach(@labels){ #use %labels to remove duplicates
    $labels{$_}++;
}

my %current;


my $term=new Term::ReadLine 'X-Labels'; # prepare terminal to read labels
my $attribs=$term->Attribs;
$attribs->{completion_entry_function}=
    $attribs->{list_completion_function};
$term->using_history;
$term->ReadHistory($history) if -r $history;

my $wrong="";

if($action eq "menu"){
    for(;;){
	$attribs->{completion_word} = [qw(append remove show clean list quit 
                                      Append Remove Show Clean List Quit)];
	$action=lc $term->
	    readline("$wrong Append/Remove/Show/Clean/List/Quit: ");
	$action=~s/ .*$//;
	last unless once($action);
    }
} else {
    once($action);
}

# update labels 
flock(LABELS, LOCK_EX)
    or die "Can't lock $labelfilename $!"; #puts an exclusive lock
seek(LABELS, 0, 0); truncate(LABELS, 0);
print LABELS join("\n", sort {$a cmp $b} keys %labels), "\n";
close(LABELS);
# update history
$term->StifleHistory($maxhistory);
$term->WriteHistory($history) or die "Couldn't write $history $!";
#DONE

sub once {
    my $action = shift;
    $wrong="";
    append(), return 1 if $action eq "append";
    remove(), return 1 if $action eq "remove";
    show(), return 1   if $action eq "show";
    clean(), return 1  if $action eq "clean";
    list(), return 1   if $action eq "list";
    return 0 if $action eq "quit";
    $wrong="Wrong action.";
    return 1;
}



sub getlabels {
    chomp(my $current = `formail -c -x X-Label < $filename`);
    $current=~s/^\s*//;
    $current=~s/\s*$//;
    my @current = split /,\s*|\s+/, $current;
    map {$current{$_}++} @current;
    print join(' ', sort {$a cmp $b} keys %current), "\n";
}    

sub modifylabels {
    my $xlabel="X-Label:";
    $xlabel.=" ". join(' ', sort {$a cmp $b} keys %current) if %current;
    print "$xlabel\n";
    system "formail -I \"$xlabel\" < $filename > $tmpfilename";
    move($tmpfilename, $filename) 
	or die "Couldn't rename $tmpfilename to $filename $!"
}


sub append {
    getlabels();
    $attribs->{completion_word} = [keys %labels];
    my $input=$term->readline("Add label(s): ");
    my @input=split /\s+/, $input;
    map {$labels{$_}++, $current{$_}++} @input; 
    modifylabels();
}

sub remove {
    getlabels();
    $attribs->{completion_word} = [keys %current];
    my $input=$term->readline("Remove label(s): ");
    my @input=split /\s+/, $input;
    map {delete $current{$_}} @input; 
    modifylabels();
}

sub show {
    getlabels();
    $term->readline("<Enter> to continue ");
}

sub list {
    open(LESS, "| fold -s | less");
    print LESS join " ", sort {$a cmp $b} keys %labels;
    close(LESS);
}

sub clean {
    getlabels();
    %current=();
    modifylabels();
}

sub test {
    system "less $filename";
}


