#!/usr/bin/perl -w

#server to fabricate some server and service metrics...

use strict;
use IO::Socket;

my $PORT = 9000;

my $server = IO::Socket::INET->new(Proto     => 'tcp',
                                   LocalPort => $PORT,
                                   Listen    => SOMAXCONN,
                                   Reuse     => 1);

die "can't setup server" unless $server;

print "[Server $0 accepting clients]\n";

my $start_time = time;

my %services = (
    "http" => 1,
    "ftp"  => 1,
    "smtp" => 1,
);

my %metrics = ();

my %cmds = (
    #availability
    Running  => sub { 1 },
    #server metrics
    Uptime   => sub { time - $start_time },
    #server/service metrics
    Requests => sub { $metrics{$_}->{Requests} },
    BytesIn  => sub { $metrics{$_}->{BytesIn} },
    BytesOut => sub { $metrics{$_}->{BytesOut} },
);

#intialize all counters to 0
for my $key ('Server', keys %services) {
    for my $metric (qw(Requests BytesIn BytesOut)) {
        $metrics{$key}->{$metric} = 0;
    }
}

sub unknown_cmd { -1 }

while (my $client = $server->accept()) {
    $client->autoflush(1);

    print "Accepted connection\n";

    $metrics{Server}->{Requests}++;

    my $cmd = <$client>;
    my $in = length $cmd;

    $metrics{Server}->{BytesIn} += $in;

    $cmd =~ s/[\r\n]//gx;

    my($metric, $component) = split /=/, $cmd;

    my $is_service = $services{$component};

    if ($is_service) {
        $metrics{$component}->{Requests}++;
        $metrics{$component}->{BytesIn} += $in;
    }

    my $handler = $cmds{$metric} || \&unknown_cmd;
    my $value;

    if (!$is_service and $component ne 'Server') {
        print "Service '$component' does not exist\n";
        $value = -1;
    }
    else {
        local $_ = $component;
        print "Metric $metric for $_\n";
        $value = $handler->();
    }

    my $out = length $value;

    $metrics{Server}->{BytesOut} += $out;

    if ($is_service) {
        $metrics{$component}->{BytesOut} += $out;
    }

    print $client $value;

    close $client;
}
