#!/usr/bin/perl -w

use Cache::Memcached;
use CGI qw(escape);
use DateTime;
use DateTime::Format::Mail;
use Date::Parse;
use File::Slurp qw( slurp ) ;
use Getopt::Long;
use JSON::XS;
use LWP;
use Text::CSV;
use strict;

my $USERNAME='dmarti';
my $PASSWORD=slurp('/home/dmarti/.twitter-password');

my $AGE = 24 * 60 * 60;
my $EXPIRE = 4 * 60 * 60;
my $VERBOSE = 0;
my $HEADER = 1;
my $DT = DateTime->now;
my $NOW = $DT->epoch();

my $NAUGHTY = 0;

my @users = ();
my @searches = ();
my %me = ();
my $name = '';
GetOptions ("user=s" => \@users,
            "search=s" => \@searches,
            "name=s" => \$name,
            "header!" => \$HEADER,
            "verbose|v" => \$VERBOSE);

my $ua = new LWP::UserAgent;
$ua->credentials( 'twitter.com:80', 'Twitter API', $USERNAME => $PASSWORD);

my $memd = new Cache::Memcached {
    'servers' => [ "127.0.0.1:11211" ],
    'debug' => 0,
    'namespace' => 'twitter_stuff'
};

my $page = 1;
my $total = 0;
my $my_followers;
my $earliest = $NOW;
my $at_res;
my %users = map {escape($_) => 1} @users;
foreach my $user(@users) {
    $me{$user} = 1;
    push (@searches, '@' . $user);
    $name = $user if !$name;
}

foreach my $search (@searches) {
    $earliest = $NOW; $page = 1;
    my $s = escape($search);
    SEARCHPAGES: while ($earliest + $AGE > $NOW) {
        my $results =
          get("http://search.twitter.com/search.json?q=$s&page=$page"); 
        last SEARCHPAGES if !@{$results->{results}}; 
        foreach my $result (@{$results->{results}}) {
            my $when = str2time($result->{created_at});
            if ($when < $earliest) { 
                $earliest = $when;
            }
            if ($when + $AGE > $NOW) {
                $users{$result->{from_user}} = 1;
                print $result->{from_user}, " said ", 
                  $result->{text}, "\n" if $VERBOSE;
            }
        }
        $page++;
    }
}

foreach my $user (keys(%users)) {
    print "checking $user..." if $VERBOSE;
    my $ui = get("http://twitter.com/users/show.json?screen_name=$user");
    next if !defined($ui) or !$ui;
    my $count = $ui->{followers_count};
    print "$count\n" if $VERBOSE;
    $total += $count;
    $my_followers += $count if $me{$user};
}

print "total $total\n" if $VERBOSE;

my $smif;
if ($total > 0) {
    $smif = (int(log($total) * 10))/10;
} else {
    $smif = "NAN";
}

my $csv = Text::CSV->new(); 
if ($HEADER) {
    $csv->combine("Date", "Name", "Impact Factor", "Own Followers",
    "Total Followers", "Searches Performed");
    print $csv->string, "\n";
}

$csv->combine(DateTime::Format::Mail->format_datetime($DT), 
  $name, $smif, $my_followers, $total, @searches);
print $csv->string, "\n";

sub get {
    my $url = shift;
    my $content;
    unless ($NAUGHTY or $content = $memd->get('NEW' . $url)) {
        my $res = $ua->get($url);
        if ($res->is_success()) {
            $content = decode_json($res->content);
            $memd->set('NEW' . $url, $content, $EXPIRE);
            $memd->set('OLD' . $url, $content, 7 * $EXPIRE);
        } elsif ($res->code == 400) {
            $NAUGHTY = 1;
            $content = $memd->get('OLD' . $url)
        } else {
            print STDERR $res->code . ' ' . $res->message . " getting $url\n";
            $content = $memd->get('OLD' . $url)
        }
    }
    return $content;
}
