use strict;
use warnings;

package Gungho::Inline;

use base qw(Gungho);
use Gungho::Request;

__PACKAGE__->mk_accessors($_) for qw(requests callback);

sub new {
    my $class = shift;
    my $config = shift;
    
    foreach my $k qw(provider handler) {
        if ($config->{$k} && ref $config->{$k} eq 'CODE') {
            $config->{$k} = {
                module => qw(Inline),
                config => {
                    callback => $config->{$k},
                },
            };
        }
    }

    $class->SUPER::new($config);
}

package Gungho::Provider::Inline;

use base qw(Gungho::Provider);
use Gungho::Request;

__PACKAGE__->mk_accessors($_) for qw(requests callback);

sub new {
    my $class = shift;
    my $self = $class->next::method(@_);
    $self->has_requests(1);
    $self->requests([]);
    $self;
}

sub setup {
    my $self = shift;
    my $callback = $self->config->{callback};
    die "``callback'' not supplied\n" unless ref $callback eq 'CODE';
    $self->callback($callback);
    $self->next::method(@_);
}

sub add_request {
    my ($self, $req) = @_;
    push @{$self->requests}, $req;
}

sub pushback_request {
    my ($self, $c, $req) = @_;
    $self->add_request($req);
}

sub dispatch {
    my ($self, $c) = @_;
    
    if ($self->callback) {
        unless ($self->callback->($c, $self)) {
            $self->callback(undef);
        }
    }
    
    my $reqs = $self->requests;
    $self->requests([]);
    while (@$reqs) {
        $self->dispatch_request($c, shift @$reqs);
    }
    
    if (! $self->callback && @{$self->requests} == 0) {
        $self->has_requests(0);
        $c->is_running(0);
    }
}

package Gungho::Handler::Inline;

use base qw(Gungho::Handler);
use Gungho::Request;

__PACKAGE__->mk_accessors($_) for qw(callback);


sub setup {
    my $self = shift;
    my $callback = $self->config->{callback};
    die "``callback'' not supplied\n" unless ref $callback eq 'CODE';
    $self->callback($callback);
    $self->next::method(@_);
}

sub handle_response {
    my ($self, $c, $req, $res) = @_;
    
    $self->callback->($req, $res, $c, $self);
}

1;
