package CouchDB;

use strict;
use warnings;

use LWP::UserAgent;
use JSON;
use Digest::MD5 qw(md5_hex);
use Data::Dump qw(dump);

sub new {
  my ($class, $host, $port, $options) = @_;

  my $ua = LWP::UserAgent->new;
  $ua->timeout(10);
  $ua->env_proxy;

  if ( $ENV{DEBUG} ) {
	$ua->add_handler("request_send",  sub { shift->dump; return });
	$ua->add_handler("response_done", sub { shift->dump; return });
  }

  return bless {
                ua       => $ua,
                host     => $host,
                port     => $port,
                base_uri => "http://$host:$port/",
               }, $class;
}

sub ua { shift->{ua} }
sub base { shift->{base_uri} }

sub request {
  my ($self, $method, $uri, $content) = @_;

  my $full_uri = $self->base . $uri;
  my $req;

  if (defined $content) {
    #Content-Type: application/json

    $req = HTTP::Request->new( $method, $full_uri, undef, encode_json $content );
    $req->header('Content-Type' => 'application/json');
  } else {
    $req = HTTP::Request->new( $method, $full_uri );
  }

  my $response = $self->ua->request($req);

  if ($response->is_success) {
    return decode_json $response->content;
  } else {
    die($response->status_line . ":" . $response->content);
  }
}

sub delete {
  my ($self, $url) = @_;

  $self->request(DELETE => $url);
}

sub get {
  my ($self, $url) = @_;

  warn "## GET $url";
  $self->request(GET => $url);
}

sub put {
  my ($self, $url, $json) = @_;

  warn "## PUT $url";
  $self->request(PUT => $url, $json);
}

sub post {
  my ($self, $url, $json) = @_;

  $self->request(POST => $url, $json);
}

sub update {
	my ($self, $url, $json) = @_;

	warn "# update_doc $url";

	my $json_md5 = md5_hex encode_json $json;
	$json->{x_sync}->{json_md5} = $json_md5;

	if ( my $old = eval { $self->get( $url ) } ) {
		warn "# old ", $old->{_rev}; #dump($old);

		if ( $json_md5 ne $old->{x_sync}->{json_md5} ) {
			$json->{_rev} = $old->{_rev};
			warn :"# update $url";
			$self->put( $url => $json );
		} else {
			warn "# unchanged $url";
		}
	} else {
		warn "# insert $url ", dump($json);
		$self->put( $url => $json );
	}

}

1;
