#!/usr/local/bin/perl -w

#
# Test reading of MH folders.
#

use Test;
use File::Compare;
use File::Copy;
use File::Spec;

use lib '..', 't';
use strict;

use Mail::Box::MH;
use Mail::Box::Mbox;

use Tools;

BEGIN {plan tests => 27}

my $orig = File::Spec->catfile('t', 'mbox.src');
my $src  = File::Spec->catfile('t', 'mh.src');

unpack_mbox($orig, $src);

warn "   * MH status BETA\n";
ok(Mail::Box::MH->foundIn($src));

my $folder = new Mail::Box::MH
  ( folder       => $src
  , lock_method  => 'NONE'
  , lazy_extract => 'ALWAYS'
  , access       => 'rw'
  );

ok(defined $folder);

# We skipped message number 13 in the production, but that shouldn't
# distrub things.

ok($folder->messages==45);
ok($folder->organization eq 'DIRECTORY');

#
# No single head should be read now, because take_headers==DELAY
# the default.
#

my $heads = 0;
foreach ($folder->messages)
{  $heads++ if $_->headIsRead;
}
ok($heads==0);

#
# Loading a header should not be done unless really necessary.
#

my $message = $folder->message(7);
ok(not $message->headIsRead);

ok($message->filename);   # already known, but should not trigger header
ok(not $message->headIsRead);

#
# Nothing should be parsed yet
#

my $parsed = 0;
foreach ($folder->messages)
{  $parsed++ if $_->isParsed;
}
ok($parsed==0);

#
# Trigger one message to get read.
#

ok($message->body);       # trigger body loading.
ok($message->isParsed);

#
# Test taking header
#

$message = $folder->message(8);
ok($message->head->get('subject'));
ok(not $message->isParsed);
ok(ref $message->head eq 'MIME::Head');

# This shouldn't cause any parsings: we do lazy extract, but Mail::Box
# will always take the `Subject' header for us.

my @subjects = map { chomp; $_ }
                  map {$_->head->get('subject') || '<undef>' }
                     $folder->messages;

$parsed = 0;
$heads  = 0;
foreach ($folder->messages)
{  $parsed++ if $_->isParsed;
   $heads++  if $_->headIsRead;
}
ok($parsed==1);            # Loaded message 7 in an earlier test.
ok($heads==45);

#
# The subjects must be the same as from the original Mail::Box::Mbox
# There are some differences with new-lines at the end of headerlines
#

my $mbox = Mail::Box::Mbox->new
  ( folder      => $orig
  , lock_method => 'NONE'
  , access      => 'r'
  );

my @fsubjects = map { chomp; $_ }
                   map {$_->head->get('subject') || '<undef>'}
                      $mbox->messages;

my (%subjects);
$subjects{$_}++ foreach @subjects;
$subjects{$_}-- foreach @fsubjects;

my $missed = 0;
foreach (keys %subjects)
{   $missed++ if $subjects{$_};
    warn "Still left: $_ ($subjects{$_}x)\n" if $subjects{$_};
}
ok(!$missed);

#
# Check if we can read a body.
#

my $msg3 = $folder->message(3);
my $body = $msg3->body;
ok(defined $body);
ok(@$body==43);       # check expected number of lines in message 3.

$folder->close;

#
# Now with partially lazy extract.
#

my $parse_size = 5000;
$folder = new Mail::Box::MH
  ( folder       => $src
  , lock_method  => 'NONE'
  , lazy_extract => $parse_size  # messages > $parse_size bytes stay unloaded.
  , access       => 'rw'
  );

ok(defined $folder);

ok($folder->messages==45);

$parsed     = 0;
$heads      = 0;
my $mistake = 0;
foreach ($folder->messages)
{   $parsed++  if $_->isParsed;
    $heads++   if $_->headIsRead;
    $mistake++ if $_->isParsed && $_->size > $parse_size;
}

ok(not $mistake);
ok(not $parsed);
ok(not $heads);

foreach (5..13)
{   $folder->message($_)->head->get('subject');
}

$parsed  = 0;
$heads   = 0;
$mistake = 0;
foreach ($folder->messages)
{   $parsed++  if $_->isParsed;
    $heads++   if $_->headIsRead;
    $mistake++ if $_->isParsed && $_->size > $parse_size;
}

ok(not $mistake);
ok($parsed == 7);
ok($heads == 9);

clean_dir $src;
