package RallyClock;

use strict;
use warnings;

use Carp qw(confess croak);
use LWP::UserAgent;
use MIME::Base64;
use XML::Simple;
use Data::Dumper;

our $VERSION = '0.01';

#
# New method
# need to pass in a hash containing your RallyClock username and API key
#
sub new {
    my $name = shift;
    my $class = ref($name) || $name;
    my $self  = {
                uri=> ''
                ,user=> ''
                ,key =>''
                ,Debug=>0
                ,@_ };
    $self->{UA} = LWP::UserAgent->new(
                          exists $self->{timeout}
                              ? (timeout => $self->{timeout})
                              : ()
                    );
    bless ($self, $class);
}


# Prepare headers
# Send HTTP request RallyClock
sub _send {

    my $self = shift;

    print "Sending ". $self->{sbuf} . "\n" if ($self->{Debug} and $self->{sbuf});

    my $auth = encode_base64($self->{user}.':'.$self->{key});

    print "AUTH ".$self->{user}.':'.$self->{key}." ".$auth."\n" if ($self->{Debug});

    my $req = HTTP::Request->new($self->{method} => $self->{url}); # Create a request
    $req->header(()
    ,'User-Agent' => 'RallyClockWS-'.$VERSION
    ,'Content-Type' => 'text/xml'
    ,'Authorization' => 'Basic '.$auth
    ,'Content-Length' => exists $self->{sbuf}
                              ? (length($self->{sbuf}))
                              : ()
    );

    $req->content($self->{sbuf}) if $self->{sbuf};
    print $req->as_string() if ($self->{Debug});
    # Pass request to the user agent and get a response back
    my $res = $self->{UA}->request($req);
    # Check the outcome of the response
    if ($res->is_success) {
        $self->{rbuf} = $res->content;
        print "Success:\n" if ($self->{Debug});
        return 1;
    } else {        
        $self->set_err("Request Error: " . $res->status_line);
        print "Request Error: " . $res->status_line."\n" if ($self->{Debug});
        return 0;
    }
}


# use XML::Simple to parse the XML and return a hash
sub parse_xml {
  my $self = shift;
  return XMLin($self->{rbuf});
}

# Get a users active timers
sub active_timer {
    my $self = shift;
    my $node = shift;
    $self->{url} = $self->{uri}.'/timers/active';
    $self->{method} = 'GET';
    $self->_send();
    my $ret_hash = $self->parse_xml() || return 0;
    if ($node) {
      if (exists $ret_hash->{$node}) {
        exists $ret_hash->{$node}->{content}
                              ? (return $ret_hash->{$node}->{content})
                              : (return $ret_hash->{$node})
      } else {
        $self->set_err("Invaild node: " .$node);
        return 0;
      }
    } else {
      return $ret_hash;
    }
}

# PUT the svn commit message to the active timer.
sub timer {
  my $self = shift;
  my $id = shift;
  my $message = shift;
  $self->{url} = $self->{uri}.'/timers/'.$id;
  $self->{method} = 'PUT';
  $self->{sbuf} = '<timer><description>'.$message.'</description><concat_desc>true</concat_desc></timer>';
  $self->_send();

}


# Just some methods to deal with errors
sub errstr {
    my $self = shift;
    $self->{errstr} = shift if @_;
    return $self->{errstr};
}

sub errcode {
    my $self = shift;
    $self->{errcode} = shift if @_;
    return $self->{errcode};
}

sub set_err {
    my $self = shift;
    my $errstr = @_ ? shift : "Unknown error";
    my $errcode = @_ ? shift : -1;
    @_ and confess;

    $self->errstr($errstr);
    $self->errcode($errcode);
}


1;