package Cuitter;
use vars qw($VERSION);
$VERSION = 0.001004;

use Mouse;
use Net::Netrc;
use Net::Twitter::Lite;
use IO::Handle;
use Encode;
use POSIX qw( strftime );
use Cache::FileCache;

with qw( MouseX::Getopt MouseX::Object::Pluggable );

has username => ( is => 'rw', isa => 'Str' );
has client => ( is => 'rw', isa => 'Object' );
has input => ( is => 'rw', isa => 'FileHandle' );
has output => ( is => 'rw', isa => 'FileHandle' );
has status => ( is => 'rw', isa => 'ArrayRef', clearer => 'clear_status' );
has rows => ( is => 'rw', isa => 'Int' );
has plugins => ( is => 'rw', isa => 'ArrayRef' );
has cache => ( is => 'rw', isa => 'Object' );

sub BUILD {
    my $self = shift;
    $| = 1;
    $self->plugins( [] ) unless $self->plugins;
    unshift @{ $self->plugins }, qw( Help Core Aliases OAuth );
    if ( $self->plugins ) {
        $self->load_plugins( @{ $self->plugins } );
        for my $plugin ( @{ $self->plugins } ) {
            my $init_method = "_init_$plugin";
            $self->$init_method;
        }
    }
    $self->rows( 6 ) unless $self->rows;
    $self->input( IO::Handle->new );
    $self->input->fdopen( fileno( STDIN ), 'r' );
    $self->output( IO::Handle->new );
    $self->output->fdopen( fileno( STDOUT ), 'w' );
    $self->cache( Cache::FileCache->new( { namespace => __PACKAGE__ } ) );
    $self->login;
    $self->loop if $self->username;
}

sub load_config {
    my $self = shift;
    my $config = LoadFile( $self->configfile ) if -e $self->configfile;
    for my $key ( keys %{ $config } ) {
        $self->$key( $config->{ "$key" } ) if $self->can( "$key" );
    }
}

sub login {
    my $self = shift;
    if ( ! Net::Netrc->lookup( 'twitter.com' ) ) {
        $self->_netrc_init;
        $self->output->print( "please restart cuitter.\n" );
    } 
    else {
        $self->_client_init(
            netrc => 1,
            clientname => __PACKAGE__,
            clientver => $VERSION,
            clienturl => 'http://cuitter.sourceforge.jp/',
            useragent => __PACKAGE__.'/'.$VERSION,
            source => 'cuitter'
        );
        $self->username( $self->client->{ username } ) unless $self->username;
        eval { $self->client->friends_timeline };
        if ( $@ ) {
            warn $@."\n";
            unlink $ENV{ HOME }.'/.netrc' if $@ =~ /^Could not authenticate you.$/;
            exit;
        }
    }
}

sub _client_init {
    my ( $self, %arg ) = @_;
    $self->client( Net::Twitter::Lite->new( %arg ) );
}

sub _netrc_init {
    my $self = shift;
    my ( $account, $password ) = @_;
    while ( !$account ) {
        $self->output->print( "What's your twitter-account? : " );
        $account = $self->input->getline;
        chomp $account;
    }
    while ( !$password ) {
        $self->output->print( "Password : " );
        $password = $self->input->getline;
        chomp $password;
    }
    my $netrc = $ENV{ HOME }. '/.netrc';
    open my $fh, '>>', $netrc;
    print $fh "machine twitter.com\nlogin $account\npassword $password\n";
    close $fh;
    chmod 0600, $netrc;
    $self->output->print( "saved to ". $ENV{ HOME }. '/.netrc'. "\n" );
}

__PACKAGE__->meta->make_immutable;

no Mouse;

1;
__END__

=head1 NAME

Cuitter - Yet Another CUI Based Twitter Client

=head1 SYNOPSIS

On your shell, execute like following.

  $ cuitter [ --plugins (SomePluginNames) ]

=head1 DESCRIPTION

Cuitter is a CUI Based Twitter Client.

=head1 Look and Feel

=head2 Prompt

 @ytnobody:

=head2 Friend Timeline

 ---
 [0] 0Day 00:00:34 ago
 @ytnobody: なにのせるの？ RT @ne********: コンテナのような規格物であれば、すんなりシャシーに載せてフェリってもらえる。
 ---
 [1] 0Day 00:03:02 ago
 @ne********: コンテナのような規格物であれば、すんなりシャシーに載せてフェリってもらえる。
 ---
 [2] 0Day 00:04:03 ago
 @su******: とてもしょんぼりしたので、もう少しお酒を飲んで気分をごまかしたいと思います。バルス！
 ---
 [3] 0Day 00:06:28 ago
 @hi******: 『少子化 + 書籍離れ + ゲーム + などなど』で 2 桁の落ち込みはリーズナブルな数値では?
 ---
 [4] 0Day 00:06:41 ago
 @ne********: ナイスエアうどんw RT @tw***: そうそう、もちっとした食感、つるっとしたのどごし。２玉ぐらいならするする～っと！
 って。なにさせるんですか。T @ne********: エアうどんを2玉どうぞ #udon
 ---
 [5] 0Day 00:08:40 ago
 @ne********: 20ftのコンテナ2本くらい欲しいなぁ
 --- Last Update: 2009-11-21 01:01:46 ---

=head3 a tweet

For example, look following.

 ---
 [1] 0Day 00:03:02 ago
 @ne********: コンテナのような規格物であれば、すんなりシャシーに載せてフェリってもらえる。

status-label is

 [1]

tweeted at 

 0Day 00:03:02 ago

tweet by

 @ne********

tweet body 

 コンテナのような規格物であれば、すんなりシャシーに載せてフェリってもらえる。

=head1 CORE COMMANDS

These commands are provided by Cuitter::Plugin::Core.

=head2 /exit /q /bye

exit from cuitter

=head2 /ft [ maxrows ]

show friends timeline

=head1 HELP COMMANDS

These commands are provided by Cuitter::Plugin::Help.

=head2 /help [ command ]

show help

=head1 LICENSE

Artistic

=head1 AUTHOR

Satoshi Azuma E<lt>ytnobody@gmail.comE<gt>

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
