#!/usr/bin/env perl

use strict;
use warnings;
use 5.010;             # does implicit 'use feature ":5.10";' => perl6 features

use File::Basename;
use File::Path;
use FindBin;
use Log::Log4perl qw(get_logger :levels);

# the tmp dir that will contain the tmp log file
my $spool_tmp = '/path/to/nfs/mount/toto'; # NFS MOUNT !!!

# Configuration in a string ...
my $conf = q(
log4perl.logger.test_l4p_nfs       = INFO, Logfile, Screen
log4perl.logger.OurProject.MyLib   = INFO, Logfile, Screen

log4perl.appender.Logfile          = Log::Log4perl::Appender::File
log4perl.appender.Logfile.filename = main.log
log4perl.appender.Logfile.append   = 0
log4perl.appender.Logfile.layout   = Log::Log4perl::Layout::PatternLayout
log4perl.appender.Logfile.layout.ConversionPattern = [%r] %F %L %m%n

log4perl.appender.Screen         = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr  = 0
log4perl.appender.Screen.layout  = Log::Log4perl::Layout::SimpleLayout
);

# ... passed as a reference to init()
Log::Log4perl::init( \$conf );
my $logger = get_logger($FindBin::Script);
my $logger_all = Log::Log4perl->get_logger("OurProject"); # not much used here, but important in our context
# Local appender to log in tmp directory.
my $local_appender;
my $local_appender_name = 'LogTmp';

# ...
$logger->info("beginning...");
$logger->info("working hard here...");

# recursive mkdir tmp
unless (-d $spool_tmp) {
    mkpath($spool_tmp) or $logger->logdie("Can't create dir $spool_tmp : $!");
    $logger->debug("created $spool_tmp");
}

# Create appender to log error in tmp directory.
$local_appender = Log::Log4perl::Appender->new(
    "Log::Log4perl::Appender::File",
    name      => $local_appender_name,
    filename  => "$spool_tmp/error.log",
    mode      => 'write',
    syswrite  => 1,
    utf8      => 1,
);
my $layout = Log::Log4perl::Layout::PatternLayout->new("%d %P %p> %F{1}:%L %M - %m%n");
$local_appender->layout($layout);
$local_appender->threshold('DEBUG');
$logger->add_appender($local_appender);
$logger_all->add_appender($local_appender); # add appender to project modules' logger

# ...
$logger->info("continue working...");
$logger->info("continue logging...");

# remove tmp appender + tmp dir
# NOTE: the goal is that, if anything went wrong, the tmp dir still exists with
# its specific log messages
# ######################################
# SOLUTION 1
$logger->remove_appender($local_appender_name);
$logger_all->remove_appender($local_appender_name);
# # ###### NEED TO DO THIS INSTEAD: ######
# # SOLUTION 2
# # "will first remove the appender from every logger in the system and then
# # will delete all references Log4perl holds to it." (Log::Log4perl)
# Log::Log4perl->eradicate_appender($local_appender_name);
# # ...but the appender is still alive and keeps filehandles open. So we need
# #  to close them explicitly. Especially under NFS, where deleted but still
# #  opened files are kept by the kernel as '.nfsxxx' (see "NFS silly
# #  rename")
# $local_appender->file_close();  # (undocumented, look into the code)
# # ######################################
rmtree($spool_tmp, {error => \my $err}); # <=== PROBLEM HERE WHEN $spool_tmp ON NFS MOUNT
if (@$err) {
    _file_path_error($err);
    exit;
}
$logger->info("removed $spool_tmp");



sub _file_path_error {
    my $err_ref = shift;

    my ($package, $filename, $line) = caller;
    $filename = basename($filename);
    for my $diag (@$err_ref) {
        my ($file, $message) = %$diag;
        if ($file eq '') {
            $logger->error("caller=$filename:$line $package, general error: $message");
        } else {
            $logger->error("caller=$filename:$line $package, problem with $file: $message");
        }
    }

    return 0;
}

