package Net::OpenVPN::Manager::Plugin::Prometheus;

use namespace::autoclean;
use Moose;
use Net::OpenVPN::Manager::Plugin;
use Net::Prometheus;

with 'Net::OpenVPN::Manager::Startable';

has 'prometheus' => (
    is => 'ro',
    default => sub {
        Net::Prometheus->new();
    },
);

sub start {
    my $self = shift;

    my $client_count = $self->prometheus->new_gauge(
        name => "ovpn_client_count",
        help => "OpenVPN user connection count",
    );

    $self->manager->add_dispatcher(sub {
        my $env = shift;

        'GET + /metrics' => sub {
            [sub {
                my $responder = shift;

                $self->manager->get_status->cb(sub {
                    my $status = $_[0]->recv;

                    $client_count->set(scalar @{$status->{clients}});
                    my $labels = [qw/cname cid ip vip/];
                    my $client_rx = $self->prometheus->new_gauge(
                        name => "ovpn_client_rx_bytes",
                        help => "OpenVPN client receive bytes",
                        labels => $labels,
                    );
                    my $client_tx = $self->prometheus->new_gauge(
                        name => "ovpn_client_tx_bytes",
                        help => "OpenVPN client transmit bytes",
                        labels => $labels,
                    );

                    map {
                        my @label_values = ($_->[0], $_->[9], $_->[1], $_->[2] || "undefined");
                        $client_rx->set(@label_values, $_->[4]);
                        $client_tx->set(@label_values, $_->[5]);
                    } @{$status->{clients}};

                    $responder->([
                        200,
                        [ "Content-Type" => "text/plain; version=0.0.4; charset=utf-8" ],
                        [ $self->prometheus->render ],
                    ]);

                    $self->prometheus->unregister($client_rx);
                    $self->prometheus->unregister($client_tx);
                });

            }];
        },
    });
}

1;
