package Net::OpenVPN::Manager::Client;

use namespace::autoclean;
use Moose;
use Moose::Util::TypeConstraints;
use MIME::Base64 qw(decode_base64);

enum 'ClientState', [qw(connecting reauthing challenging addressing establishing disconnecting connected)];

has 'cid' => (
    is => 'ro',
    isa => 'Int',
    required => 1,
);

has 'kid' => (
    is => 'rw',
    isa => 'Int',
    required => 1,
);

has 'state' => (
    is => 'rw',
    isa => 'ClientState',
    default => 'connecting',
);

has 'env' => (
    is => 'ro',
    traits => ['Hash'],
    isa => 'HashRef',
    default => sub { {} },
    handles => {
        'env_keys' => 'keys',
        'set_env' => 'set',
        'get_env' => 'get',
        'has_env' => 'exists',
    },
);

has 'attrs' => (
    is => 'ro',
    traits => ['Hash'],
    isa => 'HashRef',
    default => sub { {} },
    handles => {
        'set_attr' => 'set',
        'get_attr' => 'get',
        'has_attr' => 'exists',
    },
);

has 'config' => (
    is => 'ro',
    isa => 'ArrayRef',
    traits => ['Array'],
    default => sub { [] },
    handles => {
        configs => 'elements',
        add_config =>  'push',
    },
);

has 'addresses' => (
    is => 'ro',
    isa => 'ArrayRef',
    traits => ['Array'],
    default => sub { [] },
    handles => {
        all_addresses => 'elements',
        add_address =>  'push',
    },
);

has 'pf' => (
    is => 'ro',
    isa => 'ArrayRef',
    traits => ['Array'],
    default => sub { [] },
    handles => {
        pfs => 'elements',
        add_pf =>  'push',
    },
);

sub username {
    $_[0]->get_env('username');
}

sub has_challenge {
    my $self = shift;

    return $self->get_env('password') =~ /^SCRV1:/;
}

sub password {
    my $self = shift;

    if ($self->has_challenge) {
        my ($c, $password, $challenge) = split(/\:/, $self->get_env('password'));
        return decode_base64($password), decode_base64($challenge);
    } else {
        return $self->get_env('password');
    }
}

sub ip {
    my $self = shift;

    return $self->get_env('trusted_ip') ||
           $self->get_env('trusted_ip6') ||
           $self->get_env('untrusted_ip') ||
           $self->get_env('untrusted_ip6');
}

__PACKAGE__->meta->make_immutable;

1;
