package Audio::Tagger::Lookup::Lousy;

use strict;
use warnings;

use Audio::Tagger::Error;
use XML::Smart;
use Data::Dumper;
use Encode;

our $url = "http://mb.samfundet.no/";
our $max = 25;
our $escape = qr/[\Q\+-&|!(){}[]^"~*?:\E]/;
our $tospace = qr([\Q\/_-+:.,|\E]);

sub lookup {
	my $meta = shift;

	my $query = "$url?";
	$query .= "max=$max&" if defined $max;
	$query .= "query=";
	if (defined $meta->artist->id) {
		my $artistid = $meta->artist->id;
		$artistid =~ s/&/%26/g;
		$query .= "artistid:\"" . $artistid . "\" ";
	}
	if (defined $meta->album->id) {
		my $releaseid = $meta->album->id;
		$releaseid =~ s/&/%26/g;
		$query .= "albumid:\"" . $releaseid . "\" ";
	}
	if (defined $meta->track->id) {
		my $trackid = $meta->track->id;
		$trackid =~ s/&/%26/g;
		$query .= "trackid:\"" . $trackid . "\" ";
	}
	if (defined $meta->track->number) {
		my $tracknum = $meta->track->number;
		$tracknum =~ s/&/%26/g;
		$query .= "tracknum:" . $tracknum . " ";
	}
	if (defined $meta->track->length) {
		my $duration = $meta->track->length / 1000;
		my $counter = $duration - 10;
		$counter = 0 if $counter < 0;
		$query .= "tracklengthsec:(";
		for (; $counter <= $duration + 10; $counter++) {
			$query .= int($counter) . " ";
		}
		$query .= "0) ";
	}
	if (defined $meta->artist->name) {
		my $artist = $meta->artist->name;
		$artist =~ s/($escape)/\\$1/g;
		$artist =~ s/&/%26/g;
		$query .= lc $artist . " ";
	}
	if (defined $meta->album->name) {
		my $release = $meta->album->name;
		$release =~ s/($escape)/\\$1/g;
		$release =~ s/&/%26/g;
		$query .= lc $release . " ";
	}
	if (defined $meta->track->name) {
		my $track = $meta->track->name;
		$track =~ s/($escape)/\\$1/g;
		$track =~ s/&/%26/g;
		$query .= lc $track . " ";
	}
	if (defined $meta->file->absname && defined $meta->file->ext) {
		my $filename = $meta->file->absname;
		my $ext = $meta->file->ext;
		$filename =~ s/\.$ext$//;
		$filename =~ s#^.*/([^/]+)/([^/]+)/([^/]+$)#$1/$2/$3#;
		$filename =~ s/($tospace)/ /g;
		$filename =~ s/($escape)/\\$1/g;
		$filename =~ s/&/%26/g;
		$query .= lc $filename . " ";
	}
	chop($query);

	throw Audio::Tagger::Lookup::Error "Could not build query" if $query =~ m/query$/;

	my $result = XML::Smart->new($query);
	if ($result->null) {
		$query = Encode::decode("utf-8", $query, Encode::FB_DEFAULT);
		$result = XML::Smart->new($query);
	}

#	warn "QUERY: $query\n";
	return undef if $result->null;

	my @tracks = $result->{"metadata"}->{"track-list"}->{"track"}('@');

	foreach my $track (@tracks) {
		# track metadata
		my $t = Audio::Tagger::Meta::Track->new({
			name     => $track->{"title"}->content,
			id       => $track->{"id"}->content,
			number   => 1 + $track->{"release-list"}->{"release"}->{"track-list"}->{"offset"}->content,
			length   => $track->{"duration"}->content,
		});
		# albumartist metadata
		my $aa = Audio::Tagger::Meta::Artist->new({
			name     => $track->{"release-list"}->{"release"}->{"artist"}->{"name"}->content,
			id       => $track->{"release-list"}->{"release"}->{"artist"}->{"id"}->content,
			sortname => $track->{"release-list"}->{"release"}->{"artist"}->{"sort-name"}->content,
		});
		# release metadata
		my $r = Audio::Tagger::Meta::Album->new({
			name     => $track->{"release-list"}->{"release"}->{"title"}->content,
			id       => $track->{"release-list"}->{"release"}->{"id"}->content,
			count    => undef,
			artist   => $aa,
		});
		# artist metadata
		my $a = Audio::Tagger::Meta::Artist->new({
			name     => $track->{"artist"}->{"name"}->content,
			id       => $track->{"artist"}->{"id"}->content,
			sortname => $track->{"artist"}->{"sort-name"}->content,
		});

		$track = Audio::Tagger::Meta->new({
			album    => $r,
			track    => $t,
			artist   => $a,
		});
	}
	return @tracks;
}

1;

__END__

=head1 NAME

Audio::Tagger::Lousy - Looks up meta-data in MusicBrainz through Lousy

=head1 SYNOPSIS

This module extends Audio::Tagger::Lookup and overrides the lookup function
with the experimental Lousy seach method.

Please see Audio::Tagger::Lookup for more information and example usage.

=head1 DESCRIPTION

Currently the data-source for this module is still experimental and not yet
adopted by the MusicBrainz project.

The Lousy data-source can be thought of as a full-text search for songs, all
metadata, except ids, duration etc, is added to a single search index. By doing
this Lousy no longer cares what meta-data is what, it simply combines all
available meta-data and treats it as a plain full-text-search.  This means that
even songs where the meta-data says the title is "artist - title" or even songs
with out meta-data (but data in filename) can easily be matched.

