package Pcore::API::Moz v0.5.0;

use Pcore -dist, -class, -status;
use Pcore::Util::Digest qw[hmac_sha1];
use Pcore::HTTP::CookieJar;

has api_id      => ( is => 'ro', isa => Str,         required => 1 );
has api_key     => ( is => 'ro', isa => Str,         required => 1 );
has api_expires => ( is => 'ro', isa => PositiveInt, default  => 172_800 );    # 2 days
has proxy_pool => ( is => 'ro', isa => Maybe [ InstanceOf ['Pcore::API::ProxyPool'] ] );

has _threads => ( is => 'ro', isa => PositiveOrZeroInt, default => 0, init_arg => undef );
has _pool => ( is => 'ro', isa => ArrayRef, default => sub { [] }, init_arg => undef );
has _cookie_jar => ( is => 'ro', isa => InstanceOf ['Pcore::HTTP::CookieJar'], default => sub { Pcore::HTTP::CookieJar->new }, init_arg => undef );

sub check ( $self, $cb = undef ) {
    my $blocking_cv = defined wantarray ? AE::cv : undef;

    $self->url_metrics(
        ['google.com'],
        103079215104,
        sub ($res) {
            if ($blocking_cv) {
                $blocking_cv->send($res);
            }
            else {
                $cb->($res) if $cb;
            }

            return;
        }
    );

    return $blocking_cv ? $blocking_cv->recv : ();
}

# NOTE 10 domains max. allowed
sub url_metrics ( $self, $domains, $metric, $cb ) {
    die q[Max. 10 domains are allowed per search] if $domains->@* > 10;

    if ( $self->{_threads} > 0 ) {
        push $self->{_pool}->@*, [ $domains, $metric, $cb ];

        return;
    }

    $self->{_threads}++;

    my $url_params = {
        AccessID => $self->api_id,
        Expires  => time + $self->api_expires,
        Cols     => $metric,
    };

    $url_params->{Signature} = P->data->to_b64( hmac_sha1( $url_params->{AccessID} . $LF . $url_params->{Expires}, $self->api_key ) );

    my $url = 'https://lsapi.seomoz.com/linkscape/url-metrics/?' . P->data->to_uri($url_params);

    my $req = sub ($proxy) {
        P->http->post(
            $url,
            timeout    => 180,
            body       => P->data->to_json($domains),
            persistent => 0,
            proxy      => $proxy,
            useragent  => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0',
            cookie_jar => $self->{_cookie_jar},
            on_finish  => sub ($res) {
                my $api_res;

                if ( $res->status != 200 ) {
                    $api_res = status [ $res->status, $res->reason ];
                }
                else {
                    my $json = eval { P->data->from_json( $res->body->$* ); };

                    if ($@) {
                        $api_res = status [ 999, 'Invalid JSON body' ];
                    }
                    else {
                        $api_res = status 200;

                        for my $i ( 0 .. $domains->$#* ) {
                            $api_res->{result}->{ $domains->[$i] } = $json->[$i];
                        }
                    }
                }

                $self->{_threads}--;

                if ( my $next_call = shift $self->{_pool}->@* ) {
                    $self->url_metrics( $next_call->@* );
                }

                $cb->($api_res);

                return;
            },
        );

        return;
    };

    if ( $self->proxy_pool ) {
        $self->proxy_pool->get_slot( $url, $req );
    }
    else {
        $req->(undef);
    }

    return;
}

1;
## -----SOURCE FILTER LOG BEGIN-----
##
## PerlCritic profile "pcore-script" policy violations:
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
## | Sev. | Lines                | Policy                                                                                                         |
## |======+======================+================================================================================================================|
## |    2 | 21                   | ValuesAndExpressions::RequireNumberSeparators - Long number not separated with underscores                     |
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
##
## -----SOURCE FILTER LOG END-----
__END__
=pod

=encoding utf8

=head1 NAME

Pcore::API::Moz

=head1 SYNOPSIS

=head1 DESCRIPTION

=head1 ATTRIBUTES

=head1 METHODS

=head1 SEE ALSO

=head1 AUTHOR

zdm <zdm@softvisio.net>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by zdm.

=cut
