use strict;
use warnings;
use Net::EmptyPort qw(check_port empty_port);
use Test::More;
use t::Util;

plan skip_all => 'curl not found'
    unless prog_exists('curl');
plan skip_all => 'plackup not found'
    unless prog_exists('plackup');
plan skip_all => 'Starlet not found'
    unless system('perl -MStarlet /dev/null > /dev/null 2>&1') == 0;

my $upstream_port = empty_port();

my $guard = spawn_server(
    argv     => [ qw(plackup -s Starlet --keepalive-timeout 100 --access-log /dev/null --listen), $upstream_port, ASSETS_DIR . "/upstream.psgi" ],
    is_ready =>  sub {
        check_port($upstream_port);
    },
);

sub do_test {
    my $emit_xff = shift;
    my $emit_via = shift;
    my $emit_xff_str = $emit_xff ? "ON" : "OFF";
    my $emit_via_str = $emit_via ? "ON" : "OFF";

    my $server = spawn_h2o(<< "EOT");
proxy.emit-x-forwarded-headers: $emit_xff_str
proxy.emit-via-header: $emit_via_str
hosts:
  default:
    paths:
      /:
        proxy.reverse.url: http://127.0.0.1.XIP.IO:$upstream_port
EOT

    run_with_curl($server, sub {
            my ($proto, $port, $curl) = @_;
            my $resp = `$curl --silent $proto://127.0.0.1:$port/echo-headers`;
            if ($emit_xff) {
                like $resp, qr/^x-forwarded-for: ?127\.0\.0\.1$/mi, "x-forwarded-for";
                like $resp, qr/^x-forwarded-proto: ?$proto$/mi, "x-forwarded-proto";
            } else {
                unlike $resp, qr/^x-forwarded-for: ?127\.0\.0\.1$/mi, "x-forwarded-for not present";
                unlike $resp, qr/^x-forwarded-proto: ?$proto$/mi, "x-forwarded-proto not present";
            }
            if ($emit_via) {
                like $resp, qr/^via: ?[^ ]+ 127\.0\.0\.1:$port$/mi, "via";
            } else {
                unlike $resp, qr/^via: ?[^ ]+ 127\.0\.0\.1:$port$/mi, "via";
            }
            $resp = `$curl --silent --header 'X-Forwarded-For: 127.0.0.2' --header 'Via: 2 example.com' $proto://127.0.0.1:$port/echo-headers`;
            if ($emit_xff) {
                like $resp, qr/^x-forwarded-for: ?127\.0\.0\.2, 127\.0\.0\.1$/mi, "x-forwarded-for (append)";
            } else {
                like $resp, qr/^x-forwarded-for: ?127\.0\.0\.2$/mi, "x-forwarded-for only contains the original header";
            }
            if ($emit_via) {
                like $resp, qr/^via: ?2 example.com, [^ ]+ 127\.0\.0\.1:$port$/mi, "via (append)";
            } else {
                like $resp, qr/^via: 2 example.com$/mi, "via left as-is";
            }
        });
}

do_test(0, 0);
do_test(0, 1);
do_test(1, 0);
do_test(1, 1);

done_testing();
