#!/usr/bin/env perl

use 5.010;
use strict;
use warnings;

=head1 NAME

trrr - search torrents on CLI

=cut

use POSIX qw< ceil >;
use Encode qw< encode >;
use HTTP::Tiny;
use JSON::PP;
use Term::ANSIColor;
use App::Trrr::HotKey qw< readkey >;
use App::Trrr qw< open_app >;

unless(@ARGV){ system("perldoc trrr"); exit }
if( $ARGV[0] eq '-h' ){ system("perldoc trrr"); exit }
my @keyword = ();

my $opt = {
    os      =>  "$^O",
    seeds   =>  0,
};

for(@ARGV){
    if(/^\-/){
        s/\-//;
        if(/[a-z]/){ $opt->{key} = lc $_ } else { $opt->{seeds} = int $_ } 
    } else { push @keyword, $_ }
}

my $torrent_file = "$ENV{HOME}/Downloads/trrr.torrent";
my $url = 'http://extratorrent.cc/json/?cid=4&search=' . join '+', @keyword;

my $response = HTTP::Tiny->new->get($url);
my $results = decode_json( encode('utf8', $response->{content}) );

my $strip = sub {
    my( $item, $field ) = @_;
    my $term_width  = int `tput cols`; 
    my $size = ceil(int($item->{size})/1000/1000);
    
    my $line = $item->{key} . ' ' . $item->{seeds} . ' ' . "$item->{title}" . ' ' . $item->{category} . ' ' . $size . 'M';
    my $max = $term_width - length($line);

    if( $term_width < length($line)){
        my $strip = length($line) - $term_width;
        my $stripped_title = $term_width - $strip + 0;
        $item->{title} = substr( $item->{title},0,$max);
    } 
    my $title = $item->{title};
    my $striped = {};
    $striped->{title} = $title;
    $striped->{size} = $size;
    return $striped->{$field}
};


sub show {
    my $key = 'A';
    my $key_color;
    my $i = 1;
    my @filter = grep { int($_->{seeds}) > int($opt->{seeds}) } @{$results->{list}};
    @filter = sort { $b->{seeds} <=> $a->{seeds} } @filter;
    my @f = splice(@filter,0,15);

    for(@f){
        if( $i % 2 ){ $key_color = 'black on_white' } else { $key_color = 'white on_black' }

        $_->{key} = $key;
        my $title = $strip->($_,'title');
        my $size = $strip->($_,'size');
        my $category = $strip->($_, 'category');
        say colored([$key_color],$key) . ' ' . colored(['cyan'],$_->{seeds}) . ' ' .  colored(['yellow'],$title) . ' ' . colored(['white'],$_->{category}) . ' ' . $size . 'M' unless defined $opt->{key};
        $key++; $i++;
    }
    key(\@f);
}

sub key {
    my $filter = shift;
        get_torrent($filter) if defined $opt->{key};

        if($opt->{os} eq 'MSWin32' or $opt->{os} eq 'msys'){ 
            exit unless defined $opt->{key};
        } else {
            require App::Trrr::HotKey;
            App::Trrr::HotKey->import( 'readkey' ) ;
            $opt->{key} = readkey();
            get_torrent($filter);
        }
}

sub get_torrent {
    my $filter = shift;
    say 'saving ~/Downloads/trrr.torrent' if $opt->{key} =~ /[a-o]/;
    my @picked = grep { $_->{key} eq uc $opt->{key} } @$filter;

    for(@picked){ 
        my $torrent = HTTP::Tiny->new->get("$_->{torrentLink}");
        open(my $fh,'>',$torrent_file)||die "cant open $torrent_file: $!";
        print $fh $torrent->{content};
        close $fh;
        open_app($torrent_file);
        exit;
    }
}

show();


=head1 SYNOPSIS

CLI tool to search torrents using extratorrent API, Filters and sorts results which are then mapped to keys. Press the key with assigned letter and it will download and open torrent in your default client. 

=head1 USAGE

- filter results with as many parameters as needed

- to search torrent filter keywords sa parameters 

C<trrr keyword1 keyword2 keywordN>

- to limit results by minimum number of seeders add number as last parameter

C<trrr keyword1 keyword2 keywordN -100>

- first column is assigned key. To pick a result pres assigned key and it'll be opened in your default torrent client. 

- to pick result from previous search add letter on command line

C<trrr keyword1 keyword2 keywordN -100 -a>

- App::Trr::HotKey is taken from StackOverflow post by brian d foy

=head1 AUTHOR

Zdeněk Bohuněk. E<lt>zdenek@cpan.orgE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2016 by Zdeněk Bohuněk 

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

=cut

