package Pcore::API::Namecheap v0.3.2;

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

has api_user => ( is => 'ro', isa => Str, required => 1 );
has api_key  => ( is => 'ro', isa => Str, required => 1 );
has api_ip   => ( 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 : ();
}

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

        return;
    }

    $self->{_threads}++;

    my $domains_index->@{ $domains->@* } = ();

    my $url_params = [
        ApiUser    => $self->api_user,
        ApiKey     => $self->api_key,
        ClientIp   => $self->api_ip,
        UserName   => $self->api_user,
        Command    => 'namecheap.domains.check',
        DomainList => join( q[,], keys $domains_index->%* ),
    ];

    my $url = 'https://api.namecheap.com/xml.response?' . 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 {
                my $hash = P->data->from_xml( $res->body );

                if ( $hash->{ApiResponse}->{Errors}->[0]->{Error} ) {
                    for my $error ( $hash->{ApiResponse}->{Errors}->[0]->{Error}->@* ) {
                        if ( $error->{Number}->[0]->{content} != 2_030_280 ) {    # provider for tld was not found
                            $api_res = Pcore::API::Response->new( { status => $error->{Number}->[0]->{content}, reason => $error->{content} } );

                            last;
                        }
                    }
                }

                if ( !$api_res ) {
                    for my $domain ( $hash->{ApiResponse}->{CommandResponse}->[0]->{DomainCheckResult}->@* ) {
                        next if !exists $domains_index->{ $domain->{Domain}->[0]->{content} };

                        $domains_index->{ $domain->{Domain}->[0]->{content} } = $domain->{Available}->[0]->{content} eq 'true' ? 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;
## -----SOURCE FILTER LOG BEGIN-----
##
## PerlCritic profile "pcore-script" policy violations:
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
## | Sev. | Lines                | Policy                                                                                                         |
## |======+======================+================================================================================================================|
## |    3 | 52                   | References::ProhibitDoubleSigils - Double-sigil dereference                                                    |
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
##
## -----SOURCE FILTER LOG END-----
__END__
=pod

=encoding utf8

=head1 NAME

Pcore::API::Namecheap

=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
