#!/usr/bin/perl


# Déclaration des pragmas
use strict;
use utf8;
use open qw/:std :utf8/;

# Appel des modules externes de base
use Encode qw(decode_utf8 encode_utf8 is_utf8);
use Getopt::Long;

my ($programme) = $0 =~ m|^(?:.*/)?(.+)|;

# Variables nécessaires pour les options
my $aide       = undef;
my $fichier    = undef;
my $log        = undef;
my $motif      = undef;
my $nombre     = undef;
my $pdf        = undef;
my $repertoire = undef;

# integre les options que l'on peut donner en lancant le programme
eval	{
	$SIG{__WARN__} = sub {usage(1);};
	GetOptions(
		"fichier=s"     => \$fichier,
		"help"          => \$aide,
		"log=s"         => \$log,
		"motif=s"       => \$motif,
		"nombre=i"      => \$nombre,
		"pdf"           => \$pdf,
		"repertoire=s"  => \$repertoire,
		);
	};
$SIG{__WARN__} = sub {warn $_[0];};

usage(2) if not $repertoire and not $fichier;
usage(2) if $repertoire and (not $nombre or not $motif);

if ( $log ) {
	if ( -f $log ) {
		open(LOG, ">>:utf8", $log) or die "$!,";
		}
	else	{
		open(LOG, ">:utf8", $log) or die "$!,";
		}
	my @time = localtime();
	my $jour = (qw(Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi))[$time[6]];
	my $mois = (qw(Janvier Février Mars Avril Mai juin Juillet Août Septembre Octobre Novembre Décembre))[$time[4]];
	my $annee = $time[5] + 1900;
	my $date = "$jour $time[3] $mois $annee ";
	$date .= sprintf("%02d:%02d:%02D", $time[2], $time[1], $time[0]);
	if ( $repertoire ) {
		print LOG "\n===> $repertoire <=== $date\n\n";
		}
	elsif ( $fichier ) {
		print LOG " - $fichier : $date\n";
		}
	}
else	{
	open(LOG, ">&STDERR") or die "$!,";
	}

if ( $repertoire ) {
	if ( not -d $repertoire ) {
		print STDERR "Erreur : répertoire \"$repertoire\" absent\n";
		exit 3;
		}

	if ( $nombre < 1 ) {
		print STDERR "Erreur : le nombre de fichier doit être un entier positif\n";
		exit 4;
		}

	my @restant = ();
	foreach my $valeur (1 .. $nombre) {
		$restant[$valeur] = 1;
		}

	opendir(DIR, $repertoire) or die "$!,";
	my @fichiers = sort grep(/^${motif}_?\d+\.zip\z/, readdir DIR);
	closedir DIR;

	foreach my $fichier (@fichiers) {
		my ($valeur) = $fichier =~ /^${motif}_?(\d+)\.zip/;
		my ($base) = $fichier =~ /^(${motif}_?\d+)\.zip/;
		$restant[$valeur] = 0;
		if ( -f "$repertoire/$base.xml" ) {
			next;
			}
		traite($repertoire, $fichier, $base);
		}

	my $absent = 0;
	foreach my $valeur (1 .. $nombre) {
		if ( $restant[$valeur] ) {
			$absent ++;
			print LOG "Pas de fichier ZIP pour document n° $valeur\n";
			}
		}

	if ( $absent ) {
		print LOG "Total : $absent fichiers ZIP absents\n";
		}
	}

elsif ( $fichier ) {
	my ($chemin, $nom, $base) = $fichier =~ m|^(.*/)((.+)\.[Zz][Ii][Pp])|o;
	$chemin = "." if not $chemin;
	traite($chemin, $nom, $base);
	}


exit 0;


sub usage
{
my $code = shift;

print STDERR "\n";
print STDERR "Usage : $programme -r répertoire -n nombre_fichiers -m motif [ -l log ] \n";
print STDERR "        $programme -f fichier [ -l log ] \n";
print STDERR "        $programme -h \n";

exit $code;
}

sub erreur
{
my ($message, $code) = @_;

print LOG "$message\n";

exit $code;
}

sub traite
{
my ($directory, $file, $base) = @_;

my @pdf    = ();
my @xml    = ();
my $type   = 0;

open(INP, "unzip -l $directory/$file 2>&1 |") or die "$!,";
while(<INP>) {
	if ( /\.pdf\s*$/io ) {
		my @tmp = split(/\s+/);
		push(@pdf, $tmp[$#tmp]);
		erreur("Erreur sur fichier \"$file\"", 5) if $tmp[$#tmp] !~ /\.pdf\z/i;
		}
	elsif ( /\.xml\s*$/io ) {
		my @tmp = split(/\s+/);
		push(@xml, $tmp[$#tmp]);
		erreur("Erreur sur fichier \"$file\"", 6) if $tmp[$#tmp] !~ /\.xml\z/i;
		}
	elsif ( /\.xml\b/io ) {
		my @tmp = split(/\s+/);
		push(@xml, $tmp[$#tmp]);
		erreur("Erreur sur fichier \"$file\"", 6) if $tmp[$#tmp] !~ /\.xml\b/i;
		}
	elsif ( /unzip: +cannot find zipfile directory/o ) {
		print LOG "Le fichier \"$file\" n'est pas une archive ZIP\n";
		$type = 1;
		last;
		}
	elsif ( /: +zipfile is empty/o ) {
		print LOG "L'archive ZIP \"$file\" est vide\n";
		$type = 2;
		last;
		}
	}
close INP;

return $type if $type;

if ( $#pdf > 0 ) {
	my @tmp = ();
	foreach my $pdf (@pdf) {
		my ($debut) = $pdf =~ /^(.+)\.pdf/io;
		if (grep(/^$debut.xml\z/i, @xml) > 0) {
			push(@tmp, $pdf);
			next;
			}
		$debut =~ s/pdf/xml/o;
		if (grep(/^$debut.xml\z/, @xml) > 0) {
			push(@tmp, $pdf);
			}
		$debut =~ s/PDF/XML/o;
		if (grep(/^$debut.xml\z/i, @xml) > 0) {
			push(@tmp, $pdf);
			}
		($debut) = $pdf =~ m|^(?:.+/)?(.+)\.pdf|io;
		if (grep(/^$debut.xml\b/i, @xml) > 0) {
			push(@tmp, $pdf);
			}
		}
	if ( $#tmp == 0 ) {
		@pdf = @tmp;
		}
	elsif ( $#tmp > 0 ) {
		print LOG "Attention : PDF multiples pour \"$file\"\n";
		return 3;
		}
	elsif ( $#xml < 0 or $#xml > 0 ) {
		print LOG "Attention : cas bizarre pour \"$file\"\n";
		return 4;
		}
	}

if ( $#pdf == 0 ) {
	my ($debut) = $pdf[0] =~ /^(.+)\.pdf/io;
	my @cibles = grep(/^$debut.xml\z/i, @xml);
	if ( $#cibles == 0 ) {
		my ($racine) = $debut =~ m|^(?:.*/)?(.+)|o;
		system "unzip -j $directory/$file $cibles[0] > /dev/null";
		if ( -f "$racine.xml" ) {
			system "mv $racine.xml $directory/$base.xml"
			}
		elsif ( -f "$racine.XML" ) {
			system "mv $racine.XML $directory/$base.xml"
			}
		else	{
			print LOG "Erreur : pas de fichier \"$racine.xml\" extrait de \"$file\"\n";
			}
		}
	else	{
		if ( $debut =~ /\bpdf\b/o ) {
			$debut =~ s/pdf/xml/o;
			}
		if ( $debut =~ /\bPDF\b/o ) {
			$debut =~ s/PDF/XML/o;
			}
		@cibles = grep(/^$debut.xml\z/i, @xml);
		if ( $#cibles == 0) {
			my ($racine) = $debut =~ m|^(?:.*/)?(.+)|o;
			system "unzip -j $directory/$file $cibles[0] > /dev/null";
			if ( -f "$racine.xml" ) {
				system "mv $racine.xml $directory/$base.xml"
				}
			elsif ( -f "$racine.XML" ) {
				system "mv $racine.XML $directory/$base.xml"
				}
			else	{
				print LOG "Erreur : pas de fichier \"$racine.xml\" extrait de \"$file\"\n";
				}
			}
		elsif ( $#xml == 0 ) {
			my ($entree, $xml) = $xml[0] =~ m|^((?:.*/)?(.+\.xml.*))|;
			system "unzip -j $directory/$file $entree > /dev/null";
			if ( -f "$xml" ) {
				system "mv $xml $directory/$base.xml"
				}
			else	{
				print LOG "Erreur : pas de fichier \"$xml\" extrait de \"$file\"\n";
				}
			}
		else	{
			print LOG "Pas de XML \"$debut.xml\" pour \"$file\"\n";
			}
		}
	}
elsif ( $#xml == 0 ) {
	my ($entree, $xml) = $xml[0] =~ m|^((?:.*/)?(.+\.xml))|;
	system "unzip -j $directory/$file $entree > /dev/null";
	if ( -f "$xml" ) {
		system "mv $xml $directory/$base.xml"
		}
	else	{
		print LOG "Erreur : pas de fichier \"$xml\" extrait de \"$file\"\n";
		}
	}
elsif ( $#pdf > 0 ) {
	print LOG "Attention : encore des PDF multiples pour \"$file\"\n";
	}
else	{
	print LOG "Attention : autre cas bizarre pour \"$file\"\n";
	}

return 0;
}
