package NIST::Beacon;

# ABSTRACT: A Perl module for querying NIST's randomness beacon.

use strict;
use warnings;

our $VERSION = "1.001";

use Moo;
use XML::Simple;
use LWP::UserAgent;
use NIST::Beacon::Record;

has _agent => (is => 'ro', default => sub { LWP::UserAgent->new(agent => 'NIST-Beacon') });
has _url => (is => 'ro', default => sub { 'https://beacon.nist.gov/rest/record/' });

sub latest_record {
	my $self = shift;
	my $url = $self->_url . 'last';
	my $response = $self->_agent->get($url);

	if ($response->is_success) {
		my $data = XMLin($response->decoded_content);
		return NIST::Beacon::Record->new($data);
	}
	else {
		return;
	}
}

sub previous_record {
	my $self = shift;
	my $time = shift || time;
	my $url = $self->_url . 'previous/' . $time;
	my $response = $self->_agent->get($url);

	if ($response->is_success) {
		my $data = XMLin($response->decoded_content);
		return NIST::Beacon::Record->new($data);
	}
	else {
		return;
	}
}

sub current_record {
	my $self = shift;
	my $time = shift || time - 60;
	my $url = $self->_url . $time;
	my $response = $self->_agent->get($url);

	if ($response->is_success) {
		my $data = XMLin($response->decoded_content);
		return NIST::Beacon::Record->new($data);
	}
	else {
		return;
	}
}

sub next_record {
	my $self = shift;
	my $time = shift or return;
	my $url = $self->_url . 'next/' . $time;
	my $response = $self->_agent->get($url);

	if ($response->is_success) {
		my $data = XMLin($response->decoded_content);
		return NIST::Beacon::Record->new($data);
	}
	else {
		return;
	}
}

1;

__END__

=pod

=head1 NAME

NIST::Beacon - A Perl module for querying NIST's randomness beacon.

=head1 VERSION

version 1.001

=head1 SYNOPSIS

	use NIST::Beacon;

	my $beacon = NIST::Beacon->new;
	my $record = $beacon->latest_record;

	print "The latest sequence generated by the NIST beacon is: \n";
	print $record->current, "\n";

=head1 DESCRIPTION

NIST::Beacon provides a perl interface to the REST API of the L<NIST randomness beacon|https://beacon.nist.gov/home>.

=head2 Methods

=over 12

=item C<< latest_record >>

Returns a L<NIST::Beacon::Record> object containing the latest record
emitted by the NIST beacon.
Returns C<< undef >> if a network failure occurs.

=item C<< previous_record(timestamp) >>

Returns a L<NIST::Beacon::Record> object containing the record emitted
immediately prior to the record emitted at C<< timestamp >>.
C<< timestamp >> must be in Unix timestamp format. If no timestamp is given,
the current time is assumed.
Returns C<< undef >> if a network failure occurs or no record exists.

=item C<< current_record(timestamp) >>

Returns a L<NIST::Beacon::Record> object containing the record emitted
at C<< timestamp >>. C<< timestamp >> must be in Unix timestamp format.
If no timestamp is given, the current time minus one minuted is assumed
(to avoid querying a record that has not yet been generated).
Returns C<< undef >> if a network failure occurs or no record exists.

=item C<< next_record(timestamp) >>

Returns a L<NIST::Beacon::Record> object containing the record emitted
immediately after the record emitted at C<< timestamp >>.
C<< timestamp >> must be in Unix timestamp format. 
Returns C<< undef >> if no timestamp is given or if the timestamp is in the
future.

=back

=head1 SEE ALSO

L<NIST::Beacon::Record>

=head1 AUTHOR

William Woodruff <william@tuffbizz.com>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2014 by William Woodruff.

This is free software, licensed under:

  The MIT (X11) License

=cut
