package PVE::ExtMetric;

use strict;
use warnings;

use PVE::Status::Plugin;
use PVE::Status::Graphite;
use PVE::Status::InfluxDB;

PVE::Status::Graphite->register();
PVE::Status::InfluxDB->register();
PVE::Status::Plugin->init();

sub foreach_plug($&) {
    my ($status_cfg, $code) = @_;

    for my $id (sort keys %{$status_cfg->{ids}}) {
	my $plugin_config = $status_cfg->{ids}->{$id};
	next if $plugin_config->{disable};

	my $plugin = PVE::Status::Plugin->lookup($plugin_config->{type});
	$code->($plugin, $id, $plugin_config);
    }
}

sub update_all($$@) {
    my ($transactions, $subsystem, @params) = @_;

    my $method = "update_${subsystem}_status";

    for my $txn (@$transactions) {
	my $plugin = PVE::Status::Plugin->lookup($txn->{cfg}->{type});

	$plugin->$method($txn, @params);
    }
}

# must return a transaction hash with the format:
# {
#    cfg => $plugin_config,
#    connection => ..., # the connected socket
#    data => '', # payload, will be sent at the trannsaction flush
# }
sub transactions_start {
    my ($cfg) = @_;

    my $transactions = [];

    foreach_plug($cfg, sub {
	my ($plugin, $id, $plugin_config) = @_;

	my $connection = $plugin->_connect($plugin_config, $id);

	push @$transactions, {
	    connection => $connection,
	    cfg => $plugin_config,
	    id => $id,
	    data => '',
	};
    });

    return $transactions;
}

sub transactions_finish {
    my ($transactions) = @_;

    for my $txn (@$transactions) {
	my $plugin = PVE::Status::Plugin->lookup($txn->{cfg}->{type});

	eval { $plugin->flush_data($txn) };
	my $flush_err = $@;
	warn "$flush_err" if $flush_err;

	$plugin->_disconnect($txn->{connection}, $txn->{cfg});
	$txn->{connection} = undef;
	# avoid log spam, already got a send error; disconnect would fail too
	warn "disconnect failed: $@" if $@ && !$flush_err;
    }
}

1;
