#!/usr/local/bin/perl -w
###########################################
# shop - Keep track of purchases with git
# Mike Schilli, 2009 (m@perlmeister.com)
###########################################
use strict;
use Sysadm::Install qw(:all);
use Cache::FileCache;
use DateTime;
use DateTime::Format::Strptime;
use File::Basename;

my ($H)       = glob "~";
my $data_dir  = "data";
my $repo_name = "shop";
my $repo_dir  = "$H/$data_dir/$repo_name";

my $repo_url = 
'mschilli@box.goofhost.com:repos/shop.git';

my($action) = shift;
die "usage: $0 buy|got|list ..." unless 
                           defined $action;

mkd $repo_dir unless -d $repo_dir;

my $CACHE = Cache::FileCache->new({ 
  cache_root  => "$H/$data_dir",
  cache_depth => 0,
  namespace   => $repo_name,
});

if($action eq "buy") {
  my($item, $days) = @ARGV;
  die "usage: $0 buy item days" if 
                         !defined $days or
                         $days =~ /\D/;

  my $rec = record_new($item, $days);
  if($CACHE->get($item) ) {
      die "$item already exists.";
  }
  $CACHE->set($item, $rec);
  git_commit("Added item $item");

} elsif( $action eq "got" ) {
  my($key) = @ARGV;
  die "usage: $0 got item" unless 
                     defined $key;
  my $path = path_to_key( $key );
  git_cmd("git", "rm", "-f",
          basename($path));
  git_cmd("git", "commit", "-a", 
          "-m$key deleted");


} elsif( $action eq "list" ) {
  record_list();

} elsif( $action eq "push" ) {
  git_cmd("git", "push", 
          "origin", "master");

} elsif( $action eq "pull" ) {
  git_cmd("git", "pull", 
          "origin", "master");

} elsif( $action eq "clone" ) {
  cd "$H/$data_dir";
  rmdir $repo_name;
  cmd_run("git", "clone", $repo_url);
  cdback;

} elsif( $action eq "init" ) {
  git_cmd("git", "init");
  git_cmd("git", "remote", "add",
            "origin", $repo_url);
} else {
    die "Unknown action '$action";
}

###########################################
sub path_to_key {
###########################################
    my($key) = @_;

    return
      $CACHE->_get_backend()->_path_to_key(
                        $repo_name, $key );
}

###########################################
sub record_new {
###########################################
  my($item, $days) = @_;

  my $df = 
   DateTime::Format::Strptime->new(
     pattern   => "%F",
     time_zone => "local",
   );

  my $now = DateTime->today();
  my $exp = $now + 
      DateTime::Duration->new(
                          days => $days);

  $now->set_formatter($df);
  $exp->set_formatter($df);

  return {
      item     => $item,
      bought   => $now,
      expected => $exp,
  };
}

###########################################
sub record_list {
###########################################

  for my $key ( $CACHE->get_keys() ) {
    my $r = $CACHE->get( $key );
    print "$r->{item} ",
          "bought:$r->{bought} ",
          "exp:$r->{expected} ",
          "\n";
  }
}

###########################################
sub git_commit {
###########################################
  my($msg) = @_;

  cd $repo_dir;
  cmd_run("git", "add", ".");
  cmd_run("git", "commit", "-a", 
         "-m$msg");
  cdback;
}

###########################################
sub git_cmd {
###########################################
  cd $repo_dir;
  cmd_run(@_);
  cdback;
}

###########################################
sub cmd_run {
###########################################
    my($stdout, $stderr, $rc) = tap @_;
    if($rc != 0) {
        die $stderr;
    }
}
