#!/usr/bin/perl

package Mail::Summary::Tools::CLI::Edit;
use base qw/Mail::Summary::Tools::CLI::Command/;

use strict;
use warnings;

use Class::Autouse (<<'#\'END_USE' =~ m!(\w+::[\w:]+)!g);
#\

use Mail::Summary::Tools::Summary;
use Mail::Summary::Tools::FlatFile;
use Proc::InvokeEditor;

#'END_USE

use constant options => (
	[ 'verbose|v!'        => 'Output progress information' ],
	[ 'input|i=s'         => 'The summary file to edit' ],
	[ 'mode'              => hidden => { default => "interactive", one_of => [
		[ 'interactive'      => "Edit the file interactively (the default)" ],
		[ 'save'             => "Output a flatfile to a file or STDOUT" ],
		[ 'load'             => "Load the specified file or STDIN into the summary" ],
	] } ],
	[ 'skip|s!'           => 'Skip threads that have already been summarized' ],
	[ 'hidden|H!'         => 'Include hidden threads' ],
	[ 'links|l!'          => 'Include links to on-line archives', { default => 1 } ], # TODO shorten
	[ 'archive|a=s'       => 'The rchive to use (defaults to "google")', { default => "google" } ],
	[ 'posters|p!'        => 'Include posters names in the comment section', { default => 1 } ],
	[ 'dates|d!'          => 'Include start and end dates in the comment section', { default => 1 } ],
	[ 'misc|m!'           => 'Include misc info in the comment section', { default => 1 } ],
	[ 'extra_fields|e=s@' => "Additional fields to include in the YAML header (can be used several times)" ],
	[ 'pattern|P=s@'      => "Only include summaries matching this regex (matches against formatted text)" ],
);

sub validate {
	my ( $self, $opt, $args ) = @_;
	@$args and $opt->{$_} ||= shift @$args for qw/input/;

	unless ( $opt->{input} ) {
		$self->usage_error("Please specify an input summary YAML file.");
	}
	
	if ( @$args ) {
		$self->usage_error("Unknown arguments: @$args.");
	}

	if ( defined($opt->{load}) and $opt->{load} eq "" || $opt->{load} ) {
		$self->usage_error("You can choose one and only one of --interactive, --load or --save.") if $opt->{interactive};
		$opt->{load} = \*STDIN;
		unless ( ref( my $file = $opt->{load} ) ) {
			open my $in, "<", $file || die "open($file): $!";
			$opt->{load} = $in;
		}

		binmode $opt->{load}, ":utf8";
	}
	
	if ( defined($opt->{save}) and $opt->{save} eq "" || $opt->{save} ) {
		$self->usage_error("You can choose one and only one of --interactive, --load or --save.") if $opt->{load};
		$opt->{save} = \*STDOUT;
		unless ( ref( my $file = $opt->{save} ) ) {
			open my $out, ">", $file || die "open($file): $!";
			$opt->{save} = $out;
		}

		binmode $opt->{save}, ":utf8";
	}

	$self->{opt} = $opt;
}

sub load_summary {
	my $self = shift;
	my $opt = $self->{opt};

	Mail::Summary::Tools::Summary->load(
		$opt->{input},
		thread => {
			default_archive     => $opt->{archive},
			archive_link_params => { cache => $self->app->context->cache },
		},
	);
}

sub create_flatfile {
	my ( $self, $summary ) = @_;
	my $opt = $self->{opt};

	Mail::Summary::Tools::FlatFile->new(
		summary         => $summary,
		skip_summarized => $opt->{skip},
		include_hidden  => $opt->{hidden},
		list_posters    => $opt->{posters},
		list_dates      => $opt->{dates},
		list_misc       => $opt->{misc},
		add_links       => $opt->{links},
		extra_fields    => [ map { split ',', $_ } @{ $opt->{extra_fields} } ],
		patterns        => [ map { qr/$_/ } @{ $opt->{pattern} || [] } ],
	);
}

sub run {
	my ( $self, $opt, $args ) = @_;
	my $method = "run_$opt->{mode}";
	$self->$method;
}

sub run_save {
	my $self = shift;

	my $out = $self->{opt}{save};
	print $out $self->create_flatfile( $self->load_summary )->save;
}

sub run_load {
	my $self = shift;
	my $opt = $self->{opt};

	my $summary = $self->load_summary;
	my $flat = $self->create_flatfile( $summary );

	my $in = $opt->{load}; # aha
	my $buffer = do { local $/; <$in> };

	$flat->load($buffer);
	$summary->save( $opt->{input} );
}

sub run_interactive {
	my $self = shift;
	my $opt = $self->{opt};

	my $summary = $self->load_summary;
	my $flat = $self->create_flatfile( $summary );
	
	my $buffer = $flat->save;
	do {
		if ( $@ ) {
			my $err = $@;
			$err =~ s/^/# /mg;
			$buffer = "# There was an error in your output:\n\n$err\n\n# to abort clear the entire file\n\n$buffer";
		}

		$buffer = Proc::InvokeEditor->edit( $buffer );

		exit unless $buffer =~ /\S/;

	} until eval { $flat->load($buffer) };

	$summary->save( $opt->{input} );
}

__PACKAGE__;

__END__

=pod

=head1 NAME

Mail::Summary::Tools::CLI::Edit - Edit a YAML summary using the FlatFile format

=head1 SYNOPSIS

	# see command line usage

=head1 DESCRIPTION

=cut