# listenbrainz.pl
# CC0 https://creativecommons.org/publicdomain/zero/1.0/

use strict;
use warnings;

use Irssi;
use vars qw($VERSION %IRSSI);

my $have_uri_escape = eval { require URI::Escape; URI::Escape->import('uri_escape'); 1; };
unless ($have_uri_escape) {
	sub _uri_escape_char {
		'%' . uc(unpack('H*', $_[0]));
	}
	sub uri_escape {
		$_[0] =~ s/([^a-zA-Z0-9._~-])/_uri_escape_char($1)/ger;
	}
}

use JSON qw/decode_json/;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;

$VERSION = "2.1";
$ua->agent("irssi+listenbrainz.pl/$VERSION ");
%IRSSI = (
	authors     => "John Runyon",
	name        => "listenbrainz",
	description => "A now-playing-script which uses ListenBrainz",
	license     => 'CC0',
	url         => 'https://jfr.im/git/',
	contact     => 'git@jfr.im'
);

sub cmd_listenbrainz {
	my ($username, $server, $witem) = @_;
	unless (length $username) {
		$username = Irssi::settings_get_str('listenbrainz_username');
	}
	unless (length $username) {
		Irssi::print('%R>>%n '.$IRSSI{name}.': No username specified.');
		return;
	}

	unless (defined $witem) {
		Irssi::print("Irssi says you're not in an active window!");
		return;
	}

	my $url = "https://api.listenbrainz.org/1/user/" . uri_escape($username) . "/playing-now";
	my $req = HTTP::Request->new('GET', $url);

	my $res = $ua->request($req);
	if ($res->is_success) {
		my $data = decode_json($res->content);
		unless (scalar @{ $data->{payload}{listens} }) {
			$witem->print("ListenBrainz says you're not listening to anything!");
			return;
		}
		my %track = %{ $data->{payload}{listens}[0]{track_metadata} };
		my $s = sprintf(Irssi::settings_get_str('listenbrainz_format'), $username, $track{track_name}, $track{artist_name}, $track{release_name}, $track{additional_info}{media_player} // $track{additional_info}{listening_from});
		if (Irssi::settings_get_bool('listenbrainz_append_link') && defined $track{mbid_mapping}{recording_mbid}) {
			$s .= ' https://musicbrainz.org/recording/' . $track{mbid_mapping}{recording_mbid};
		}
		$witem->command("say $s");
	} else {
		$witem->print("ListenBrainz request Failed!");
		if (Irssi::settings_get_bool('listenbrainz_debug')) {
			print $req->url;
			print $req->content;
			print $res->status_line;
			print $res->content;
		}
	}
}

sub cmd_np {
	if (Irssi::settings_get_bool('listenbrainz_alias_np')) {
		cmd_listenbrainz(@_);
	}
}

Irssi::settings_add_bool('listenbrainz', 'listenbrainz_debug', 0);           # Output info when an error occurs?
Irssi::settings_add_bool('listenbrainz', 'listenbrainz_alias_np', 1);        # Should /np work as an alias for /listenbrainz? Set to OFF if also using lastfm.pl.
Irssi::settings_add_str('listenbrainz', 'listenbrainz_username', '');        # Default username when none is supplied
# Output format - 1: username, 2: track, 3: artist, 4: album, 5: player
Irssi::settings_add_str('listenbrainz', 'listenbrainz_format', '%1$s playing %2$s by %3$s (%4$s) (from %5$s)');
Irssi::settings_add_bool('listenbrainz', 'listenbrainz_append_link', 1);

Irssi::command_bind('listenbrainz', 'cmd_listenbrainz', 'listenbrainz');
Irssi::command_bind('np', 'cmd_np', 'listenbrainz');
Irssi::print('%G>>%n '.$IRSSI{name}.' '.$VERSION.' loaded');
