use Test::More;
use t::TestPsgi;
use LWP::Protocol::PSGI;
use JSON;
use Plack::Test;
use HTTP::Request::Common;
use File::Temp 'tempdir';
no warnings 'redefine';

my @postedValues;

my $lokiDeferDir = tempdir( 'lokiTmpXXXXX', DIR => 't', CLEANUP => 1 );
my @TMP          = @ARGV;
@ARGV = ( '--defer-dir', $lokiDeferDir );
require_ok('./eg/lokiSender');
@ARGV = @TMP;

LWP::Protocol::PSGI->register(
    sub {
        my $req = Plack::Request->new(@_);
        ok( $req->method =~ /^post$/i, 'Method is POST' );
        ok( ( $req->uri eq 'http://localhost:3100/loki/api/v1/push' ),
            'URL is good' );
        my $s = $req->content;
        ok( $s = eval { JSON::from_json($s) }, 'Posted values are JSON' );
        push @postedValues, $s;
        return [ 200, [], [] ];
    }
);

sub runTest {
    my ($defer) = @_;
    @postedValues = ();
    my $args = {
        logger      => 't::TestLogger',
        userLogger  => 'Lemonldap::NG::Common::Logger::Loki',
        auditLogger => 'Lemonldap::NG::Common::AuditLogger::UserLoggerJSON',
        logLevel    => 'info',
        ( $defer ? ( lokiDeferDir => $lokiDeferDir ) : () ),
    };
    my $psgi = new_ok( 't::TestPsgi' => [$args] );
    $psgi->init($args);

    my $server = Plack::Test->create( $psgi->run );
    my $res    = $server->request( GET "/" );
    is( $res->code, 200, "Returned HTTP code 200" );
    my $i;
    if ($defer) {
        ok( !@postedValues, 'Loki logs deferred' );
        &sendLogs;
    }
    ok( @postedValues, 'Loki API called' );

    foreach my $log (
        sort {
            $a->{streams}->[0]->{values}->[0]->[0]
              <=> $b->{streams}->[0]->{values}->[0]->[0]
        } @postedValues
      )
    {
        foreach my $stream ( @{ $log->{streams} } ) {
            is( $stream->{stream}->{job}, 'llng', 'job is llng' );
            ok( $stream->{stream}->{level} =~ /^(info|notice)$/,
                "log level is $1" );
            ok( $stream->{stream}->{instance}, 'instance exists' );
            is( $stream->{stream}->{env}, 'prod', 'env is prod' );
            foreach my $value ( @{ $stream->{values} } ) {
                ok( $value->[0] =~ /^\d+$/, 'timestamp is set' );
                my $msg = $value->[1];
                ok( $msg, 'Message exists' );

   # First message is generated by userLogger, so a string, nexts are audit logs
                if ($i) {
                    my $j = eval { JSON::from_json($msg) };
                    ok( ( $j and ref $j ), 'Audit message is JSON encoded' );
                }
                else {
                    ok( $msg, 'Get msg' );
                    is(
                        $msg,
                        'User logger trace',
                        'Userlogger message is a string'
                    );
                }
                $i++;
            }
        }
    }
}

subtest "Check Loki API" => sub {
    runTest();
};

subtest "Check Loki API with deferred send" => sub {
    runTest(1);
};

done_testing();
