package Pcore::API::Dynadot v0.2.0;

use Pcore -dist, -class;
use Pcore::API::Response;

has api_key => ( is => 'ro', isa => Str, required => 1 );
has bind_ip => ( is => 'ro', isa => Maybe [Str] );

has _threads => ( is => 'ro', isa => PositiveOrZeroInt, default => 0, init_arg => undef );
has _pool => ( is => 'ro', isa => ArrayRef, default => sub { [] }, init_arg => undef );

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

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

            return;
        }
    );

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

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

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

        return;
    }

    $self->{_threads}++;

    my $url_params = [
        key     => $self->api_key,
        command => 'search',
    ];

    my $i = 0;

    my $domains_index = {};

    for my $domain ( $domains->@* ) {
        next if exists $domains_index->{$domain};

        $domains_index->{$domain} = undef;

        push $url_params->@*, 'domain' . $i++, $domain;
    }

    my $url = 'https://api.dynadot.com/api2.html?' . P->data->to_uri($url_params);

    P->http->get(
        $url,
        persistent => 0,
        timeout    => 180,
        recurse    => 0,
        bind_ip    => $self->bind_ip,
        on_finish  => sub ($res) {
            my $api_res;

            if ( $res->status != 200 ) {
                $api_res = Pcore::API::Response->new( { status => $res->status, reason => $res->reason } );
            }
            else {

                # parse response
                my @lines = split /\x0A/sm, $res->body->$*;

                my ( $status, $error ) = split /,/sm, shift @lines;

                if ( $status ne 'ok' ) {
                    chomp $error;

                    $api_res = Pcore::API::Response->new( { status => 999, reason => $error } );
                }
                else {
                    shift @lines;

                    for my $line (@lines) {
                        chomp $line;

                        my @fields = split /,/sm, $line;

                        if ( $fields[3] eq 'yes' ) {
                            $domains_index->{ $fields[1] } = 1;
                        }
                        elsif ( $fields[3] eq 'no' ) {
                            $domains_index->{ $fields[1] } = 0;
                        }
                    }

                    $api_res = Pcore::API::Response->new( { status => 200 } );

                    $api_res->{result} = $domains_index;
                }
            }

            $self->{_threads}--;

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

            $cb->($api_res);

            return;
        }
    );

    return;
}

1;
__END__
=pod

=encoding utf8

=head1 NAME

Pcore::API::Dynadot

=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
