### ----------------------------------------------------
### -- IRC::Log::Textual
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: t/01-basic.rakutest
### ----------------------------------------------------
use Test;
use IRC::Log::Textual;

my $filename = '2021-04-22';
my $date     = $filename;
my $pos      = -1;

my $path     = $?FILE.IO.sibling: "$filename.txt";
my $log      = IRC::Log::Textual.new: $path;

my @entries    = $log.entries.List;
my $nr-entries = +@entries;

sub test-common(
  $entry, $class, $hour, $minute, $ordinal, $nick-index, $nick,
  $control, $conversation, $comment,
) {
    subtest $comment => {
        plan 15;

        isa-ok $entry, IRC::Log::{$class};
        is $entry.date,     $date,    "is .date correct: $date";
        is $entry.hour,     $hour,    "is .hour correct: $hour";
        is $entry.minute,   $minute,  "is .minute correct: $minute";
        is $entry.ordinal,  $ordinal, "is .ordinal correct: $ordinal";
        is $entry.nick,     $nick,    "is .nick correct: $nick";
        is $entry.pos,      ++$pos,   "is .pos correct: $pos";

        is-deeply $entry.control, $control,
          "is .control ok: $control";
        is-deeply $entry.conversation, $conversation,
          "is .conversation ok: $conversation";
        is-deeply $entry.prefix eq '*** ', $entry.control,
          "is the prefix as expected: $entry.prefix()";
        is-deeply
          $entry.sender,
          $entry ~~ IRC::Log::Message ?? $entry.nick !! '',
          "is the sender as expected: $entry.sender()";

        is +$entry.entries.elems, $nr-entries,
          'is nr-entries correct';
        is $entry.hhmm, sprintf('%02d%02d',$hour,$minute),
          'is .hhmm correct';
        is $entry.hh-mm, sprintf('%02d:%02d',$hour,$minute),
          'is .hh-mm correct';
        is $entry.target, (
          $ordinal
            ?? sprintf($date ~ 'Z%02s:%02d-%04d', $hour, $minute, $ordinal)
            !! sprintf($date ~ 'Z%02s:%02d',      $hour, $minute)
        ), 'is .target correct';
    }
}

plan 65 + @entries;

is-deeply IRC::Log::Textual.IO2Date($path), $date.Date,
  'was the date elided correctly';
is @entries.map(*.gist).join("\n"),
  $?FILE.IO.sibling("$filename.gist").slurp.chomp,
  'does .gist generate the raw log again';

isa-ok $log, IRC::Log::Textual;
is-deeply $log.date, $date,      'is the date correct';
is-deeply $log.Date, $date.Date, 'is the Date correct';
is $log.problems.elems, 0, 'did we see any problems';
is $log.nr-control-entries,      6, 'is nr control entries correct';
is $log.nr-conversation-entries, 3, 'is nr conversation entries correct';

my $first-entry = $log.first-entry;
is $first-entry.target, "2021-04-22Z05:36", 'is first entry ok';
is $first-entry.pos, 0, 'is first entry position ok';
is-deeply $first-entry.prev, Nil, 'do we get Nil on out of bounds on .prev';
is $first-entry.next.pos, 1, 'is second entry position ok';

my $last-entry = $log.last-entry;
is $last-entry.target,  "2021-04-22Z23:50", 'is last entry ok';
is $last-entry.pos,  7, 'is last entry position ok';
is-deeply $last-entry.next, Nil, 'do we get Nil on out of bounds on .next';
is $last-entry.prev.pos, 6, 'is penultimate position ok';

is $log.first-target, "2021-04-22Z05:36", 'is first target ok';
is $log.last-target,  "2021-04-22Z23:50", 'is last target ok';
is $log.last-topic-change.text, "Perl Sucks!", 'is last topic change ok';

my $picked = @entries.roll;
is-deeply $log.target-entry($picked.target), $picked,
  'can we find a randomly picked entry by target';

given "2021-04-22Z09:35" -> $target {
    is $log.target-index($target), 3, 'is the target index correct';
    is-deeply $log.entries-lt-target($target), @entries[0..2],
      'did we get entries before target';
    is-deeply $log.entries-le-target($target), @entries[0..3],
      'did we get entries until target';
    is-deeply $log.entries-ge-target($target), @entries[3..7],
      'did we get entries from target';
    is-deeply $log.entries-gt-target($target), @entries[4..7],
      'did we get entries after target';
}

given "2021-04-22Z05:36" -> $target {
    is-deeply $log.entries-lt-target($target), Empty,
      'did we get no entries before first target';
    is-deeply $log.entries-le-target($target), (@entries[0],),
      'did we get entry of first target';
}

given "2021-04-22Z23:50" -> $target {
    is-deeply $log.entries-ge-target($target), (@entries[7],),
      'did we get entry of last target';
    is-deeply $log.entries-gt-target($target), Empty,
      'did we get no entries after last target';
}

is-deeply $log.entries-of-nick-names(<lizmat lizmmat_>),
  @entries[3,6], 'did we see all lizmats entries';
is-deeply $log.entries-of-nick-names(<lizmat woolfy>),
  (@entries[6],), 'did we see all lizmats entries';
is-deeply $log.entries-of-nick-names(<snoopy charlie>),
  Empty, 'did we see not see any snoopy and charlie entries';

nok @entries.head.prev, 'No previous entry before first';
nok @entries.tail.next, 'No next entry after last';
is-deeply @entries[3].prev, @entries[2], 'Previous entry check';
is-deeply @entries[3].next, @entries[4], 'Next entry check';

my $entry = @entries.shift;
test-common $entry, 'Joined', 5, 36, 0, 1, 'MasterDuke', True, False,
  'test joining';

$entry = @entries.shift;
test-common $entry, 'Message', 8, 1, 0, 1, 'MasterDuke', False, True,
  'test message';
is $entry.text, 'any objections to merging ?',
  'is text ok in the message';

$entry = @entries.shift;
test-common $entry, 'Self-Reference', 8, 1, 1, 2, 'sena_kun', False, True,
  'test message';
is $entry.text, 'still awaits the release blocker',
  'is text ok in the self-reference';

$entry = @entries.shift;
test-common $entry, 'Nick', 9, 35, 0, 3, 'lizmmat_', True, False,
  'test nick change';
is $entry.new-nick, 'lizmat',
  'is new nick ok';

$entry = @entries.shift;
test-common $entry, 'Left', 11, 31, 0, 4, 'nine', True, False,
  'test leaving';

$entry = @entries.shift;
test-common $entry, 'Mode', 22, 47, 0, 5, 'ChanServ', True, False,
  'test mode';
is $entry.flags, '+o',
  'are the flags ok';
is-deeply $entry.nick-names, Array[Str].new('tyil'),
  'are the nicks ok';

$entry = @entries.shift;
test-common $entry, 'Topic', 23, 48, 0, 6, 'lizmat', True, True,
  'test topic';
is $entry.text, 'Perl Sucks!',
  'is the text ok';

$entry = @entries.shift;
test-common $entry, 'Kick', 23, 50, 0, 7, 'tyil', True, False,
  'test kick';
is $entry.kickee, 'lizmat',
  'is the kickee ok';
is-deeply $entry.spec, '(lizmat)',
  'is the spec ok';

is +@entries, 0, 'did we see all the entries';

is $log.nick-names.elems, 8, 'did we see 1 + 7 nicks';
subtest 'test all known nicks' => {
    plan 7;
    for <ChanServ lizmat lizmmat_ nine sena_kun tyil> -> $nick {
        is $log.entries-of-nick($nick).elems, 1, "did we see $nick once";
    }
    is $log.entries-of-nick('MasterDuke').elems, 2, "saw MasterDuke twice";
}

my $raw = $path.slurp;
my $slurped = IRC::Log::Textual.new: $raw, $date;
isa-ok $slurped, IRC::Log::Textual;
is $slurped.raw, $raw, 'does the raw log match';
is $slurped.entries.elems, $nr-entries, 'did we get correct number of entries';
is-deeply $slurped.date, $date, 'is the date correct again';
is $slurped.problems.elems, 0, 'did we see any problems';
is $slurped.nr-control-entries,      6, 'is nr control entries correct';
is $slurped.nr-conversation-entries, 3, 'is nr conversation entries correct';

is $log.update($?FILE.IO.sibling: "$filename.txt").elems, 0,
  'Did the update without changes indicate 0 entries were added?';

is $log.update($?FILE.IO.sibling: $filename ~ '-with-additions.txt').elems, 2,
  'Did the update indicate 2 entries were added?';
is $log.entries.elems, $nr-entries + 2, 'did we really get 2 extra entries';
is $log.nr-control-entries,      7, 'is nr control entries correct';
is $log.nr-conversation-entries, 4, 'is nr conversation entries correct';
@entries = $log.entries.Seq.skip($nr-entries);
$nr-entries += 2;

$entry = @entries.shift;
test-common $entry, 'Joined', 23, 53, 0, 6, 'lizmat', True, False,
  'test joining extra entry';

$entry = @entries.shift;
test-common $entry, 'Message', 23, 53, 1, 6, 'lizmat', False, True,
  'test message extra entry';
is $entry.text, 'Thank you, I needed that :-)',
  'is text ok in the message of extra entry';

is $log.nick-names.elems, 8, 'did we see 1 + 7 nicks again';
subtest 'test all known nicks' => {
    plan 7;
    for <ChanServ lizmmat_ nine sena_kun tyil> -> $nick {
        is $log.entries-of-nick($nick).elems, 1, "did we see $nick once again";
    }
    is $log.entries-of-nick('MasterDuke').elems, 2, "saw MasterDuke twice";
    is $log.entries-of-nick('lizmat').elems, 3, "did we see lizmat thrice";
}

$log = IRC::Log::Textual.new: "", Date.today;
is $log.entries.elems, 0, 'did we get a proper empty log';

# vim: expandtab shiftwidth=4


