#!/usr/bin/env perl
use strict;
use warnings;
use lib qw(lib);
use App::Rad;
use Config::General qw(ParseConfig);
use Getopt::Long qw(GetOptions);
use Net::Rackspace::Notes qw(notes);
use Pod::Usage qw(pod2usage);
use Term::ReadPassword qw(read_password);

sub setup {
    my $c = shift;
    $c->register_commands({
        add    => 'add a new note, content is read from stdin',
        append => 'append the content of stdin to the note',
        delete => 'delete the note',
        list   => 'lists id and subject of all notes',
        show   => 'show the contents of the note',
    });
    my ($email, $password) = get_login_info();
    $c->stash->{racknotes} = Net::Rackspace::Notes->new(
        email    => $email,
        password => $password,
    );
}

App::Rad->run();

#-------------------------------------------------------------------------------
# Function definitions ---------------------------------------------------------

sub add {
    my $c = shift;
    my $subject = $c->options->{subject};
    my $body = do { local $/; <STDIN> };
    my $racknotes = $c->stash->{racknotes};
    my $response = $racknotes->add_note($subject, $body);
    return "status: " . $response->status_line;
    #print $response->content . "\n" unless $response->is_success;
}

sub append {
    my $c = shift;
    my $note_id = $c->options->{num};
    my $body = do { local $/; <STDIN> };
    my $num = $note_id;
    my $note = note($num);
    my $content = $note->{content} . $body;
    my $racknotes = $c->stash->{racknotes};
    my $response = $racknotes->add_note($note->{subject}, $content);
    $response = $racknotes->delete_note($num);
    return "status: " . $response->status_line;
}

sub delete {
    my $c = shift;
    my $note_id = $c->options->{num};
    my $racknotes = $c->stash->{racknotes};
    my $response = $racknotes->delete_note($note_id);
    return "status: " . $response->status_line;
    #print $response->content . "\n" unless $response->is_success;
}

sub show {
    my $c = shift;
    my $note_id = $c->options->{num};
    my $racknotes = $c->stash->{racknotes};
    return $racknotes->notes->[$note_id]{content};
}

sub list {
    my $c = shift;
    my $count = 0;
    my $racknotes = $c->stash->{racknotes};
    my @notes = @{$racknotes->notes};
    return join "\n", map sprintf("%2d: %s", $count++, $_->{subject}), @notes;
}

sub get_login_info {
    my $c = shift;
    my ($email, $password);
    my $config_path = "$ENV{HOME}/.racknotes";

    if (-r $config_path) {
        my %config = ParseConfig($config_path);
        ($email, $password) = @config{qw(email password)};
    } else {
        print "If you don't want to enter your account info each time, you\n",
            "can create a config file at $config_path with 2 entries:\n",
            "  email = bob\@foo.com\n",
            "  password = foo\n\n";

        print "email: ";
        chomp($email = <STDIN>);
        die "$email is not a valid email address\n"
            unless $email =~ /.+@.+\..+/;

        $password = read_password('password: ');
    }
    return ($email, $password);
}


__END__

=head1 NAME

racknotes - A command line interface to Rackspace Email Notes.

=head1 SYNOPSIS

  Options:
    -h, --help              display this help message
        --add=subject       add a new note, content is read from stdin
        --append=noteid     append the content of stdin to the note
    -d, --delete=noteid     delete the note
    -l, --list              lists id and subject of all notes
    -s, --show=noteid       show the contents of the note

=head1 OPTIONS

=over 4

=item B<-h|--help>

Print a brief help message.

=item B<add --subject=SUBJECT>

Add a new note with the given subject.
The contents of the note will be read from stdin.

=item B<append --num=NUM>

Append the content of stdin to the note.

=item B<delete --num=NUM>

Delete the note.

=item B<list>

List the id and subject of all the notes.

=item B<show --num=NUM>

Show the contents of the note.

=back

=head1 DESCRIPTION

This program is a command line tool to interface with Rackspace Email Notes.

=cut
