use 5.010;
use utf8;
use MooseX::Declare;

BEGIN
{
	$WWW::DataWiki::Trait::Negotiator::AUTHORITY = 'cpan:TOBYINK';
	$WWW::DataWiki::Trait::Negotiator::VERSION   = '0.000_01';
}

role WWW::DataWiki::Trait::Negotiator
	# for WWW::DataWiki::Resource
{
	use HTTP::Headers qw[];
	use HTTP::Negotiate qw[];
	
	requires 'available_formats';
	requires 'extension_map';
	
	method media_type ($fmt)
	{
		foreach ($self->available_formats)
		{
			if (lc $_->[0] eq lc $fmt)
			{
				return wantarray ? ($_->[2], $_->[4]) : $_->[2];
			}
		}
		return wantarray ? ('application/octet-stream', 'utf-8') : 'application/octet-stream';
	}
	
	method extension_for ($media_type)
	{
		my %types = %{ $self->extension_map // {} };
		while (my ($ext, $mt) = each %types)
		{
			return $ext if lc $media_type eq lc $mt;
		}
	}
	
	method negotiate ($ctx)
	{
		my $request = $ctx->req;
		my $headers = $request->headers->clone;

		# Double-hack
		eval {
			# Hack
			if ($ctx->action->class eq 'WWW::DataWiki::Controller::Page')
			{
				my $extension = $ctx->request->captures->[1];
				my $type = defined $extension ? $self->extension_map->{$extension} : undef;
				if (defined $type)
					{ $headers->header(Accept => $type) }
			}
		};

		if (exists $request->query_params->{'accept'})
			{ $headers->header(Accept => $request->query_params->{'accept'}) }
		if (exists $request->query_params->{'accept-encoding'})
			{ $headers->header(Accept_Encoding => $request->query_params->{'accept-encoding'}) }
				
		my $gzip = (($headers->header('Accept-Encoding')//'') =~ /\bgzip\b/i);
		my $pref = HTTP::Negotiate::choose([$self->available_formats], $headers);
		my ($media, $charset) = $self->media_type($pref);

		$ctx->add_http_vary(qw/Negotiate Accept Accept-Encoding/);
		
		return ($pref, $media, $charset, $gzip);
	}
}

