package Bing::Azure::WebSearch;

# ABSTRACT: Bing search API for the Microsoft Windows Azure Marketplace for web search
# Please read the Bing Brand guidelines before displaying search results

use strict;
use warnings;

use LWP::UserAgent;
use XML::Simple;
use URI::Escape;
use Data::Dumper;
use MIME::Base64;
use JSON;
use XML::Simple;
use HTTP::Headers;
my $xml = new XML::Simple;
my $ua = LWP::UserAgent->new;

use vars qw/$errstr $headers/;
use constant SERVICEROOTURL => 'https://api.datamarket.azure.com/Bing/SearchWeb/'; # The standard URL for websearch only!

sub new {
	my ($self) = @_;

	if (defined($_[1])) {
		# Set the required basic authorization header to authenticate the API user
		$headers = new HTTP::Headers(
    			'Authorization' => 'Basic ' . MIME::Base64::encode($_[1] . ':' . $_[1])
		);
	} else {
		$errstr = 'accountKey is required to perform a Bing API Search request';
		return;
	}

	return $self;
}

sub errstr {
	$errstr;
}

sub search {
	my $args = scalar @_ % 2 ? shift : {@_};
	my $querystring = SERVICEROOTURL;

	# The only mandatory value is the query itself

	if (defined($args->{bing}->{query})) {
		$querystring .= 'Web?Query=%27' . $args->{bing}->{query} . '%27';
	} else {
		$errstr = 'Query (search term) is required';
		return;
	}

	# Determine which type of API results to parse (output format for this package)
	# Option 1. Atom (XML)
	# Option 2. json (JSON)

	my $output_format = (defined($args->{bing}->{format})) ? $args->{bing}->{format} : 'atom';
	$querystring .= '&$format=' . lc($output_format);

	# Total amount of results to show (Bing limits to 50)
	if (defined($args->{bing}->{limit})) {
		$querystring .= '&$top=' . $args->{bing}->{limit};		
	} else {
		$querystring .= '&$top=50';
	}

	# Search offset for skipping the first search results
	if (defined($args->{bing}->{offset})) {
		$querystring .= '&$skip=' . $args->{bing}->{offset};
	}

	if (defined($args->{bing}->{market})) {
		$querystring .= '&Market=%27' . $args->{bing}->{market} . '%27';
	}

	# Building the HTTP GET request including header with authentication
	my $request = new HTTP::Request(
		"GET",
		$querystring,
		$headers
	);

	my $resp = $ua->request($request);

	# Check if the request returns succesfull (HTTP 200)
	unless ($resp->is_success) {
		$errstr = $resp->status_line;
		return;
	}

	# Return results according to the chosen output format
	if ($output_format eq 'atom') {
		$xml = new XML::Simple;
		return $xml->XMLin($resp->content);
	} elsif ($output_format eq 'json') {
		my $json = new JSON;
		return $json->decode($resp->content);
	} else {
		$errstr = 'No valid output format selected';
		return;
	}
}

