#!/usr/local/bin/perl -w
###########################################
# google-drive-check - collect access token
# Mike Schilli, 2012 (m@perlmeister.com)
###########################################
use strict;
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Headers;
use HTTP::Request::Common;
use File::Basename;
use YAML qw( LoadFile DumpFile );
use JSON qw( from_json );

my( $home )  = glob "~";
my $cfg_file = "$home/.google-drive.yml";
my $syncdir  = "$home/books";
my @books_local = 
  map { basename $_ } <$syncdir/*.pdf>;

my $cfg = LoadFile $cfg_file;

if( $cfg->{ expires } - 60 < time() ) {
    warn "Token needs to be refreshed.";
    token_refresh( $cfg );
    DumpFile( $cfg_file, $cfg );
}

my $req = HTTP::Request->new(
  GET => 'https://www.googleapis.com/' .
    'drive/v2/files?maxResults=3000',
  HTTP::Headers->new( Authorization => 
      "Bearer " . $cfg->{ access_token })
);

my $ua = LWP::UserAgent->new();
my $resp = $ua->request( $req );

if( ! $resp->is_success() ) {
    die $resp->message();
}

my $data = from_json( $resp->content() );

my %books_remote = ();

for my $item ( @{ $data->{ items } } ) {
  if( $item->{ kind } eq "drive#file" ) {
    my $file = $item->{ originalFilename };
    next if !defined $file; 
    $books_remote{ $file } = 1;
  }
}

for my $book ( @books_local ) {
  if( !exists $books_remote{ $book } ) {
    print "Book not saved yet: [$book]\n";
  }
}

###########################################
sub token_refresh {
###########################################
  my( $cfg ) = @_;

  my $req = &HTTP::Request::Common::POST(
    'https://accounts.google.com/o' .
    '/oauth2/token',
    [
      refresh_token => 
        $cfg->{ refresh_token },
      client_id     => 
        $cfg->{ client_id },
      client_secret => 
        $cfg->{ client_secret },
      grant_type    => 'refresh_token',
    ]
  );

  my $ua = LWP::UserAgent->new();
  my $resp = $ua->request($req);

  if ( $resp->is_success() ) {
    my $data = 
      from_json( $resp->content() );
    $cfg->{ access_token } = 
      $data->{ access_token };
    $cfg->{ expires } = 
      time() + $data->{ expires_in };
    return 1;
  }

  warn $resp->status_line();
  return undef;
}
