### ----------------------------------------------------
### -- Log::Dispatch
### -- Licenses: Artistic-2.0
### -- Authors: Vadim Belman
### -- File: t/040-threaded.rakutest
### ----------------------------------------------------
use Test;
use Test::Output;
use Log::Dispatch;
use Log::Dispatch::Source;
use Log::Dispatch::Destination;

plan 2;

constant THREAD-COUNT = 500;
BEGIN $*SCHEDULER = ThreadPoolScheduler.new(:max_threads(THREAD-COUNT + 32));

my @msg-obj;
my @msg-line;

my class LogDest does Log::Dispatch::Destination {
    method report(Log::Dispatch::Msg:D $message) {
        @msg-obj.push: $message;
        @msg-line.append: |$message.fmt-lines;
    }
}

my class LogSrc does Log::Dispatch::Source {
    method log-source-name { "MultiThr" }
}

subtest "Concurrent logging" => {
    plan 2;
    my $logger = Log::Dispatch.new;
    my $inst = LogSrc.new;
    $logger.add: $inst;
    $logger.add: LogDest;

    my $starter = Promise.new;
    my @ready;
    my @worker;

    for ^THREAD-COUNT -> $id {
        @ready.push: my $ready = Promise.new;
        @worker.push: start {
            $ready.keep;
            await $starter;
            $inst.log: "THREAD ", $id;
        }
    }

    await @ready;
    $starter.keep;
    await @worker;

    $logger.shutdown;

    is +@msg-obj, THREAD-COUNT, "all messages are logged";

    my %ids;

    for @msg-obj -> $msg-obj {
        %ids{$msg-obj.msg} = True;
    }

    my $all-set = True;
    for ^THREAD-COUNT -> $id {
        $all-set &= %ids{"THREAD " ~ $id};
    }

    ok $all-set, "all thread ID has been logged";
}

subtest "Thread ID in output" => {
    my $logger = Log::Dispatch.new;
    my $inst = LogSrc.new;
    $logger.add: $inst;
    $logger.add: LogDest;
    @msg-obj = ();
    @msg-line = ();

    my $id-str = ~($*RAKU.compiler.version >= v2022.06 ?? $*STACK-ID !! $*THREAD.id);

    $inst.log: "No ID";

    $inst.use-thread-id;

    $inst.log: "WITH THREAD ID";

    $logger.shutdown;

    like @msg-line[0], /'[MultiThr] No ID'/, "no thread ID by default";
    like @msg-line[1], /'[MultiThr:' \s+ $id-str '] WITH THREAD ID'/, "thread ID is included when requested";
}

done-testing;


