#!perl -w
# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# Idle client memory usage test
use v5.12.1;
use PublicInbox::TestCommon;
use File::Temp qw(tempdir);
use Socket qw(SOCK_STREAM IPPROTO_TCP SOL_SOCKET);
require_mods(qw(-nntpd));
require PublicInbox::InboxWritable;
require PublicInbox::SearchIdx;
use PublicInbox::Syscall;
use PublicInbox::DS;
my $version = 2; # v2 needs newer git
require_git('2.6') if $version >= 2;
use_ok 'IO::Socket::SSL';
my ($cert, $key) = qw(certs/server-cert.pem certs/server-key.pem);
unless (-r $key && -r $cert) {
	plan skip_all =>
		"certs/ missing for $0, run ./certs/create-certs.perl";
}
use_ok 'PublicInbox::TLS';
my ($tmpdir, $for_destroy) = tmpdir();
my $err = "$tmpdir/stderr.log";
my $out = "$tmpdir/stdout.log";
my $mainrepo = $tmpdir;
my $pi_config = "$tmpdir/pi_config";
my $group = 'test-nntpd-tls';
my $addr = $group . '@example.com';
local $SIG{PIPE} = 'IGNORE'; # for NNTPC (below)
my $nntps = tcp_server();
my $ibx = PublicInbox::Inbox->new({
	inboxdir => $mainrepo,
	name => 'nntpd-tls',
	version => $version,
	-primary_address => $addr,
	indexlevel => 'basic',
});
$ibx = PublicInbox::InboxWritable->new($ibx, {nproc=>1});
$ibx->init_inbox(0);
{
	open my $fh, '>', $pi_config or die "open: $!\n";
	print $fh <<EOF
[publicinbox "nntpd-tls"]
	mainrepo = $mainrepo
	address = $addr
	indexlevel = basic
	newsgroup = $group
EOF
	;
	close $fh or die "close: $!\n";
}

{
	my $im = $ibx->importer(0);
	my $eml = eml_load('t/data/0001.patch');
	ok($im->add($eml), 'message added');
	$im->done;
	if ($version == 1) {
		my $s = PublicInbox::SearchIdx->new($ibx, 1);
		$s->index_sync;
	}
}

my $nntps_addr = tcp_host_port($nntps);
my $env = { PI_CONFIG => $pi_config };
my $tls = $ENV{TLS} // 1;
my $args = $tls ? ["--cert=$cert", "--key=$key", "-lnntps://$nntps_addr"] : [];
my $cmd = [ '-nntpd', '-W0', @$args, "--stdout=$out", "--stderr=$err" ];

# run_mode=0 ensures Test::More FDs don't get shared
my $td = start_script($cmd, $env, { 3 => $nntps, run_mode => 0 });
my %ssl_opt = (
	SSL_hostname => 'server.local',
	SSL_verifycn_name => 'server.local',
	SSL_verify_mode => SSL_VERIFY_PEER(),
	SSL_ca_file => 'certs/test-ca.pem',
);
my $ctx = IO::Socket::SSL::SSL_Context->new(%ssl_opt);

# cf. https://rt.cpan.org/Ticket/Display.html?id=129463
my $mode = eval { Net::SSLeay::MODE_RELEASE_BUFFERS() };
if ($mode && $ctx->{context}) {
	eval { Net::SSLeay::CTX_set_mode($ctx->{context}, $mode) };
	warn "W: $@ (setting SSL_MODE_RELEASE_BUFFERS)\n" if $@;
}

$ssl_opt{SSL_reuse_ctx} = $ctx;
$ssl_opt{SSL_startHandshake} = 0;

my %opt = (
	Proto => 'tcp',
	PeerAddr => $nntps_addr,
	Type => SOCK_STREAM,
	Blocking => 0
);
chomp(my $nfd = `/bin/sh -c 'ulimit -n'`);
$nfd -= 10;
ok($nfd > 0, 'positive FD count');
my $MAX_FD = 10000;
$nfd = $MAX_FD if $nfd >= $MAX_FD;
our $DONE = 0;
sub once { 0 }; # stops event loop

# setup the event loop so that it exits at every step
# while we're still doing connect(2)
$PublicInbox::DS::loop_timeout = 0;
local @PublicInbox::DS::post_loop_do = (\&once);

foreach my $n (1..$nfd) {
	my $io = tcp_connect($nntps, Blocking => 0);
	$io = IO::Socket::SSL->start_SSL($io, %ssl_opt) if $tls;
	NNTPC->new($io);

	# one step through the event loop
	# do a little work as we connect:
	PublicInbox::DS::event_loop();

	# try not to overflow the listen() backlog:
	if (!($n % 128) && $n != $DONE) {
		diag("nr: ($n) $DONE/$nfd");
		$PublicInbox::DS::loop_timeout = -1;
		@PublicInbox::DS::post_loop_do = (sub { $DONE != $n });

		# clear the backlog:
		PublicInbox::DS::event_loop();

		# resume looping
		$PublicInbox::DS::loop_timeout = 0;
		@PublicInbox::DS::post_loop_do = (\&once);
	}
}
my $pid = $td->{pid};
my $dump_rss = sub {
	return if $^O ne 'linux';
	open(my $f, '<', "/proc/$pid/status") or return;
	diag(grep(/RssAnon/, <$f>));
};
$dump_rss->();

# run the event loop normally, now:
if ($DONE != $nfd) {
	$PublicInbox::DS::loop_timeout = -1;
	@PublicInbox::DS::post_loop_do = (sub {
		diag "done: ".time." $DONE";
		$DONE != $nfd;
	});
	PublicInbox::DS::event_loop();
}

is($nfd, $DONE, 'done');
$dump_rss->();
if ($^O eq 'linux') {
	diag "  SELF lsof | wc -l ".`lsof -p $$ |wc -l`;
	diag "SERVER lsof | wc -l ".`lsof -p $pid |wc -l`;
}
PublicInbox::DS->Reset;
$td->kill;
$td->join;
is($?, 0, 'no error in exited process');
done_testing();

package NNTPC;
use v5.12;
use parent qw(PublicInbox::DS);
use PublicInbox::Syscall qw(EPOLLOUT EPOLLONESHOT);
use Data::Dumper;

# return true if complete, false if incomplete (or failure)
sub connect_tls_step ($) {
	my ($self) = @_;
	my $sock = $self->{sock} or return;
	return 1 if $sock->connect_SSL;
	return $self->drop("$!") unless $!{EAGAIN};
	if (my $ev = PublicInbox::TLS::epollbit()) {
		unshift @{$self->{wbuf}}, \&connect_tls_step;
		PublicInbox::DS::epwait($self->{sock}, $ev | EPOLLONESHOT);
		0;
	} else {
		$self->drop('BUG? EAGAIN but '.PublicInbox::TLS::err());
	}
}

sub event_step ($) {
	my ($self) = @_;

	# TLS negotiation happens in flush_write via {wbuf}
	return unless $self->flush_write && $self->{sock};

	if ($self->{step} == -2) {
		$self->do_read(\(my $buf = ''), 128) or return;
		$buf =~ /\A201 / or die "no greeting";
		$self->{step} = -1;
		$self->write(\"COMPRESS DEFLATE\r\n");
	}
	if ($self->{step} == -1) {
		$self->do_read(\(my $buf = ''), 128) or return;
		$buf =~ /\A20[0-9] / or die "no compression $buf";
		NNTPCdeflate->enable($self);
		$self->{step} = 1;
		$self->write(\"DATE\r\n");
	}
	if ($self->{step} == 0) {
		$self->do_read(\(my $buf = ''), 128) or return;
		$buf =~ /\A201 / or die "no greeting";
		$self->{step} = 1;
		$self->write(\"DATE\r\n");
	}
	if ($self->{step} == 1) {
		$self->do_read(\(my $buf = ''), 128) or return;
		$buf =~ /\A111 / or die 'no date';
		no warnings 'once';
		$::DONE++;
		$self->{step} = 2; # all done
	} else {
		die "$self->{step} Should never get here ". Dumper($self);
	}
}

sub new {
	my ($class, $io) = @_;
	my $self = bless {}, $class;

	# wait for connect(), and maybe SSL_connect()
	$self->SUPER::new($io, EPOLLOUT|EPOLLONESHOT);
	$self->{wbuf} = [ \&connect_tls_step ] if $io->can('connect_SSL');
	$self->{step} = -2; # determines where we start event_step
	$self;
};

1;
package NNTPCdeflate;
use v5.12;
our @ISA = qw(NNTPC PublicInbox::DS);
use Compress::Raw::Zlib;
use PublicInbox::DSdeflate;
BEGIN {
	*write = \&PublicInbox::DSdeflate::write;
	*do_read = \&PublicInbox::DSdeflate::do_read;
	*event_step = \&NNTPC::event_step;
	*flush_write = \&PublicInbox::DS::flush_write;
	*close = \&PublicInbox::DS::close;
}

sub enable {
	my ($class, $self) = @_;
	my %ZIN_OPT = ( -WindowBits => -15, -AppendOutput => 1 );
	my ($in, $err) = Compress::Raw::Zlib::Inflate->new(%ZIN_OPT);
	die "Inflate->new failed: $err" if $err != Z_OK;
	bless $self, $class;
	$self->{zin} = $in;
}

1;
