
# A10::AX
# Jeremy Kister 2011.02.15
# Released under Perl's Artistic License
# http://jeremy.kister.net./

package A10::AX;

use strict;
use LWP::UserAgent;
use XML::Simple;

sub new {
    my $class = shift;
    my %args;
    if( @_ % 2 ){
        my $host = shift;
        %args = @_;
        $args{host} = $host;
    }else{
        %args = @_;
    }

    die "[lbconfig] missing CONF\n" unless($args{conf});

    my $self = bless(\%args, $class);
    $self->{class} = $class;
    $self->{uad}   = "lbconfig/$args{conf}{version} (compatible; MSIE 8.0)" unless($args{uad});
    $self->{url}   = "http://$self->{host}/services/rest/V1.1/?";
    $self->{xs}    = XML::Simple->new();
    $self->{ua}    = LWP::UserAgent->new( timeout    => 120,
                                          agent      => $self->{uad},
                                          keep_alive => 1,
                                          protocols_allowed => [ 'http', 'https' ],
                                        );

    
    my $username = $self->{conf}{hosts}{ $self->{host} }{un};
    my $password = $self->{conf}{hosts}{ $self->{host} }{pw};
    die "[lbconfig] could not find username/password for device $self->{host}\n" unless($username && $password);

    my $rest = $self->{url} .
               'method=authenticate&username=' . $username .
               '&password=' . $password;

    my $href = $self->process_request($rest);
    if($href->{status} eq 'ok'){
        $self->{url} .= 'session_id=' . $href->{session_id};
    }else{
        die "[lbconfig] could not authenticate to $self->{host}\n";
    }

    return $self;
}

sub api {
    my $self = shift;
    my $method = shift || die "[lbconfig] api err1\n";

    my $rest = $self->{url} . "&method=$method";
    my $href = $self->process_request($rest);

    return ($href->{status} eq 'ok') ? $href : 0;
}

sub close {
    my $self = shift;

    my $href = $self->api('session.close');

    return ($href->{status} eq 'ok') ? 1 : 0;
}

sub process_request {
    my $self = shift;
    my $rest = shift || die "[lbconfig] process_api err1\n";

    my $r = $self->{ua}->get($rest);
    if( $r->is_success ){
        my $xs = XML::Simple->new;
        return $xs->XMLin($r->decoded_content);
    }else{
        die "[lbconfig] bad response from API: " . $r->status_line . "\n";
    }
}

sub type {
    my $self = shift;
    my $input = shift;

    warn "[lbconfig] type input undef\n" unless defined $input;

    my %h = (  2 => 'TCP',   3 => 'UDP',    8 => 'RTSP',
               9 => 'FTP',  10 => 'MMS',   11 => 'SIP',       12 => 'Fast-HTTP',
              14 => 'HTTP', 15 => 'HTTPS', 16 => 'SSL-Proxy', 17 => 'SMTP',
            );

    return( $h{$input} || "*Unknown* ($input)");
}

sub status {
    my $self = shift;
    my $input = shift;

    warn "[lbconfig] status input undef\n" unless defined $input;

    my %h = ( 0 => 'Disabled', 1 => 'Up',   2 => 'PartUp',
              3 => 'FuncUp',   4 => 'Down', 5 => 'Unknown',
            );

    return( $h{$input} || "*Unknown* ($input)" );
}

sub lb_method {
    my $self = shift;
    my $input = shift;

    warn "[lbconfig] lb_method input undef\n" unless defined $input;
    
    my %h = ( 0 => 'Round Robin', 1 => 'Weighted Round Robin',  2 => 'Least Connection',
              3 => 'Least Connection On Service Port',          4 => 'Service Least Connection',
              5 => 'Weighted Least Connection On Service Port', 6 => 'Fastest Response Time',
              7 => 'Least Request',                             8 => 'Strict Round Robbin',
            );

    # NB 4 is fudged, inferred from config. - documentation says 4 is invalid

    return( $h{$input} || "*Unknown* ($input)" );
}

1;
