#!/usr/bin/env perl
# Feersum native app with TLS and prefork for benchmarking
use strict;
use warnings;
use blib;
use Feersum;
use Socket qw(SOMAXCONN);
use IO::Socket::INET;
use EV;
use POSIX qw(_exit);
use Getopt::Long;

my $port  = 5003;
my $forks = 3;
my $cert  = 'eg/ssl-proxy/server.crt';
my $key   = 'eg/ssl-proxy/server.key';
my $h2    = 0;

GetOptions(
    'port=i'    => \$port,
    'workers=i' => \$forks,
    'cert=s'    => \$cert,
    'key=s'     => \$key,
    'h2!'       => \$h2,
) or die "Usage: $0 [--port PORT] [--workers N] [--cert FILE] [--key FILE] [--h2]\n";

my $socket = IO::Socket::INET->new(
    LocalAddr => "127.0.0.1:$port",
    ReuseAddr => 1,
    Proto     => 'tcp',
    Listen    => SOMAXCONN,
    Blocking  => 0,
) or die "Cannot create socket: $!";

# Fork workers
my @pids;
for my $i (1 .. $forks) {
    my $pid = fork;
    die "fork failed: $!" unless defined $pid;

    if ($pid == 0) {
        # Child process
        EV::default_loop()->loop_fork;

        my $feersum = Feersum->new();
        $feersum->use_socket($socket);
        $feersum->set_keepalive(1);
        $feersum->read_timeout(300);  # 5min; avoid false idle-timeout under load

        die "Feersum not compiled with TLS support\n" unless $feersum->has_tls();

        $feersum->set_tls(
            cert_file => $cert,
            key_file  => $key,
            ($h2 ? (h2 => 1) : ()),
        );

        my $body = "Hello, World!";
        $feersum->request_handler(sub {
            my $req = shift;
            $req->send_response(200, ['Content-Type' => 'text/plain'], \$body);
        });

        EV::run;
        _exit(0);
    }
    push @pids, $pid;
}

my $proto = $h2 ? "h2" : "https";
print "Feersum native TLS prefork server on https://127.0.0.1:$port/ ($proto, workers: $forks)\n";

# Parent waits for children
$SIG{INT} = $SIG{TERM} = sub {
    kill 'TERM', @pids;
    exit 0;
};

waitpid($_, 0) for @pids;
