package Parp::Folders;

=head1 NAME

Parp::Folders - delivery folder management

=head1 SYNOPSIS

Used internally.

=head1 DESCRIPTION

This library provides routines to do with the actual delivery of
messages to folders.

=head1 ROUTINES

=cut

use strict;
use warnings;

use Fcntl qw(:seek);
use POSIX qw(strftime);

use Parp::Utils qw(vprint check_file_dir error fatal);
use Parp::Locking;

use base qw(Exporter);
our @EXPORT_OK = qw(append_to_folder folder_substs);

=head2 folder_substs($folder)

Performs strftime substitution on the folder name, and also
replaces C<%q> with the quarter of the current year.

=cut

sub folder_substs {
  my ($folder) = @_;
  my @now = localtime;
  my $quarter = int($now[4]/3 + 1);
  $folder = strftime($folder, @now);
  $folder =~ s/%q/$quarter/g;
  return $folder;
}

=head2 append_to_folder($filename, $mail)

Appends the C<$mail> object, which can be a Mail::Box::Message or a
Mail::Internet, to the given file.  Locking is taken care of.

=cut

my $mgr;

sub append_to_folder {
  my ($file, $mail) = @_;

  my $message = $mail->mail;

  if (eval { $message->isa('Mail::Box::Message') }) {
    require Mail::Box::Manager;
    $mgr ||= Mail::Box::Manager->new(default_folder_type => 'mbox');

    eval {
      $mgr->appendMessages($file, $message, access => 'rw', create => 1);
    };
    error("Mail::Box::Manager::appendMessages() failed: $@") if $@;
  }
  else {
    _append_to_mbox($file, $mail);
  }
}

sub _append_to_mbox {
  my ($file, $mail) = @_;
  
  check_file_dir($file);

  open(MBOX, ">>$file") or
    fatal(5, "Couldn't open $file for delivery: $!");
  lock_file($file, *MBOX);
  seek MBOX, 0, SEEK_END;       # necessary?
  print MBOX $mail->fake_mbox_from;
  print MBOX $mail->as_mbox_string;
  close(MBOX);
}


1;
