package WebService::OANDA::ExchangeRates::Response;

use Moo;

use HTTP::Response;
use JSON::XS qw{decode_json};
use Try::Tiny;

has http_response => (
    is  => 'rw',
    handles => {
        is_success  => 'is_success',
        is_error    => 'is_error',
        raw_data    => 'content',
        http_status => 'code',
    },
    required => 1,
);

has data => ( is  => 'rw' );

sub BUILD {
    my $self = shift;
    my $data;

    try {
        $data = JSON::XS::decode_json( $self->raw_data );
    }
    catch {
        $data = {
            code => undef,
            message => sprintf(
                'Failed to decode content(%s): $%s', $self->raw_data, $_
            )
        };

        # if we failed to decode the json on a successful query, we'll consider
        # this an outlier and force a 500
        if ($self->is_success) {
            $self->http_response(
                HTTP::Response->new(500, undef, undef, $self->raw_data)
            );
        }

    };

    $self->data($data);
}

sub error_message {
    my $self = shift;

    return unless $self->is_error;
    return $self->data->{message};
}

sub error_code {
    my $self = shift;
    return unless $self->is_error;
    return $self->data->{code};
}

1;

__END__

=head1 NAME

WebService::OANDA::ExchangeRates::Response - the response object from all API
calls in L<WebService::OANDA::ExchangeRates>.

=head1 SYNOPSIS

  my $api = WebService::OANDA::ExchangeRates->new(api_key => 'YOUR_API_KEY');

  my $response = $api->get_rates(
      base_currency => 'USD',
      quote         => [ qw{ EUR CAD } ],
  );

  if ($response->is_success) {
      print $response->data->{base_currency}, "\n";
  }
  else {
      print $respone->error_message, "\n";
  }



=head1 DESCRIPTION

This module is used as the result generated by any API method called in
L<WebService::OANDA::ExchangeRates>.  It automatically deserializes the data
into a native Perl data structure and provides information about the request
and response via an instance of L<HTTP::Response>.  You should never need to
instantiate this directly as it will be provided.

=head1 METHODS

=head2 Constructor

=over 4

=item $response = WebService::OANDA::ExchangeRates::Response->new( http_response => $http_response_object );

Constructor takes just an L<HTTP::Response> object which will attempt to
deserialize the JSON into a native data structure.

=back

=head2 data

Contains the deserialized data structure of the API request.

=head2 error_code

A convenience method. If the response was an error, returns the contents of
C<< $response->data->{code} >>.

=head2 error_message

A convenience method. If the response was an error, returns the contents of
C<< $response->data->{message} >>.

=head2 http_response

Accessor for the L<HTTP::Response> object generated by the API request.

=head2 http_status

Convenience method to access C<< $response->http_response->code >> to determine
the HTTP status code.

=head2 is_error

=head2 is_success

Convenience methods that proxy through to the same methods of the
C<< $response->http_response >> instance.

=head2 raw_data

Convenience method to examine the raw serialized data returned by the API.  A
proxied request to C<< $response->http_response->content >>.

=head1 SEE ALSO

=over 4

=item * L<HTTP::Response>

=item * L<WebService::OANDA::ExchangeRates>

=back

=head1 SUPPORT

=head2 Bug/Feature requests

Please file a ticket at the repository for this code on github at:

L<https://github.com/oanda/perl-webservice-oanda-exchangerates>

=head1 AUTHOR

  Dave Doyle <ddoyle@oanda.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by OANDA Corporation.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
