package DJabberd::Queue::ServerOut;
use strict;
use warnings;

use base 'DJabberd::Queue';
use DJabberd::Queue qw(NO_CONN RESOLVING);
use fields (
            'domain',
            'del_source',
            );

use DJabberd::Connection::ServerOut;

use DJabberd::Log;

our $logger = DJabberd::Log->get_logger;

sub new {
    my ($class, %opts) = @_;

#    warn( join ",", keys %opts );
#    warn( $opts{domain});

    my $domain = delete $opts{domain}
        or Carp::confess "domain required";
    my $del_source = delete $opts{source}
        or die "delivery 'source' required";
    my $self = fields::new($class);
    $self->SUPER::new( %opts );

    $self->{domain} = $domain;
    $self->{del_source} = $del_source;

    return $self;
}

sub give_up_connecting {
    my $self = shift;
    $logger->error("Connection error while connecting to $self->{domain}, giving up");
}

sub domain {
    my $self = shift;
    return $self->{domain};
}

sub queue_stanza {
    my $self = shift;
    # Passthrough, maybe we should warn and depricate?
    return $self->SUPER::enqueue( @_ );
}

sub start_connecting {
    my $self = shift;
    $logger->debug("Starting connection to domain '$self->{domain}'");
    die unless $self->{state} == NO_CONN;

    # TODO: moratorium/exponential backoff on attempting to deliver to
    # something that's recently failed to connect.  instead, immediately
    # call ->failed_to_connect without even trying.

    $self->{state} = RESOLVING;

    # async DNS lookup
    DJabberd::DNS->srv(service  => "_xmpp-server._tcp",
                       domain   => $self->{domain},
                       callback => sub {
                           $self->endpoints(@_);
                           $logger->debug("Resolver callback for '$self->{domain}': [@_]");
                           $self->{state} = NO_CONN;
                           $self->SUPER::start_connecting;
                       });
}

sub new_connection {
    my $self = shift;
    my %opts = @_;

    return DJabberd::Connection::ServerOut->new(%opts);
}

1;
