#!/usr/bin/perl 

package Socrata;

use strict;
use warnings;
use WWW::Curl::Easy;
use JSON;
use URI::Escape;
use Carp;



sub new {
	my $class = shift;
	my $rh_params = shift;
	my $self = {};
	bless $self, ref $class || $class;

	if (! $rh_params) {
		$rh_params = {};
	}
	$self->_initialize($rh_params);

	return $self;
}


sub _initialize{
	 my ($self, $rh_params) = @_;

	# base URL
	#The base URL for this Socrata API, ex: http://data.medicare.gov/api or http://www.socrata.com/api
	$self->{base_url} = $rh_params->{base_url} || "http://nycopendata.socrata.com/api";
	# app token
	$self->{app_token} = $rh_params->{app_token} || "";
	# username and password used for authentication requests
	$self->{username} = $rh_params->{username} || "";
	$self->{password} = $rh_params->{password} || "";

}


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

	# use passed in path for dataset
	my $full_url = $self->{base_url} . $path;

	#define default headers to send
	my @headers = (
		'Accept: application/json',
		'Content-type: application/json',
		"X-App-Token: " . $self->{app_token},
	);

	#define parameters
	my $qstring;
	my @paramlist;
	foreach (keys(%$rh_params)){
		push (@paramlist,join("=", uri_escape($_), uri_escape($rh_params->{$_})));
	}
	$qstring = join("&", @paramlist);
	if ($qstring ne ""){
		$full_url .= "?" .$qstring;
	}
#	print $full_url . "\n\n";

	# initialize curl object and set options
	my $curl = WWW::Curl::Easy->new();
	$curl->setopt(CURLOPT_HEADER, 1);
	$curl->setopt(CURLOPT_URL, $full_url);
	$curl->setopt(CURLOPT_HTTPHEADER, \@headers);

	# add suthentication if username and password are defined
	if ($self->{username} ne ""){
		$curl->setopt(CURLOPT_USERPWD, $self->{username} . ":" . $self->{password});
	}

	#define reposnse varaiable
	my $response_body;
	$curl->setopt(CURLOPT_WRITEDATA,\$response_body);

	# perform the curl
	my $retcode = $curl->perform;
	my $obj_response = {};

	# if good response
	if ($retcode == 0){

		# remove headers from output
		my @response = split("\n",$response_body);
		my $count =0;
		foreach (@response){
			if ($_ !~ /{/){
				$count++;
			} else{
				last;
			}
		}
		for (my $i=0; $i<$count; $i++){
			shift @response;
		}
		$response_body = join("\n", @response);

		$obj_response = decode_json($response_body);
		return $obj_response;
	} else {
		croak "An error happened: " . $curl->strerror($retcode) . " " . $curl->errbuf . "\n";
	}
}


#module must end on a happy note;
1;

__END__

=head1 NAME

Socrata - handle the interface with Socrata Open Data API

=head1 SYNOPSIS

    use Socrata;
    my %options = (
                base_url =>  "https://nycopendata.socrata.com",
                );
    my $socrata = new Socrata(\%options);
    my $rh_result = $socrata->get("/api/views/74cu-ncm4/rows.json", {});

=head1 DESCRIPTION

This library provides a simple wrapper for accessing some of the features of the Socrata Open Data API from PHP. Currently it only supports HTTP GET operations, but in the future it will support other methods as well.

The library is very simple. To access the Socrata API, you first instantiate a "Socrata" object, passing in the API base URL for the data site you wish to access. The Base URL is always the URL for the root of the datasite, with "/api" added to the path (ex: http://www.socrata.com/api or http://data.medicare.gov/api). Then you can use its included methods to make simple API calls:

This library provides an interface to the SODA Publisher API. If you're new to all this, you may want to brush up on the getting started guide.
dev.socrata.com/publisher/getting-started

If you're curious about how things work under the hood, you can also browse the API documentation directly.
http://opendata.socrata.com/api/docs/

=head1 VERSION

    1.0

=head1 OPTIONS

Additional options when creating the new Socrata object

   use Socrata;
   my %options = (
                base_url  =>  "https://nycopendata.socrata.com",
		app_token => "", #optional
		username  => "", #optional for authenticated requests
		password  => "", #optional for authenticated requests
                );
    my $socrata = new Socrata(\%options);

You may also add additional criteria on the get function, for searching or retrieving subsets of the data

   my $rh_result = $socrata->get("/api/views/74cu-ncm4/rows.json",
                                {
                                "method"=>"getRows",
                                "start"=>120,
                                "length" =>60,
                                });

	
=head1 AUTHOR

Benjamin Marcus
ben<at>fourthfloorequipment.com 

=head1 BUGS

Please report bugs relevant to this module to <ben[at]fourthfloorequipment.com>.

=head1 COPYRIGHT AND LICENSE

Copyright 2012 by Benjamin Marcus

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=cut
