#!/usr/bin/perl -w 
use XML::RSS; 
use Unicode::String qw(utf8);

use utf8;   
use Unicode::Normalize;
use Encode;
use strict;
use XML::XPath;


#Le script de l'extraction des patron à partir des fichiers qui contiennent l'annotation morpho-syntaxique (forme, lemme, catégorie)
#Modifié par Uliana Petrunina
#Juin 2014
#Usage : perl arbre-xml-txt-1606-rub.pl SORTIE-treetagger motif.txt



#--------------------------------------------------------------------
# Définition globale de l'encodage utf8 pour l'entrée et la sortie du script
binmode STDIN,  ':encoding(utf8)';
binmode STDOUT, ':encoding(utf8)';


# On vérifie le nombre d'arguments de l'appel au script ($0 : le nom du script)
if($#ARGV!=1){print "usage : perl $0 racine fichier_motif";exit;}


my $racine= shift @ARGV;
$racine=~ s/[\/]$//;
print " Le repertoire de départ est : $racine\n";

my $patterns_file = shift @ARGV;

#D'abord il faut parcourir le dossier avec la liste des fichiers, lire chaque fichier qui correspond à treetagger

#########################################PARCOURS DES FICHIERS##########################################################
&recurseTousFics($racine);


#########################PROCEDURES POUR : construction des chemins XPath et extraction du motif#########################
sub construit_XPath{

	my $local_ligne=shift @_;
       
	#On initialise le chemin XPath
	my $search_path="";
       
	#On supprime avec la fonction chomp un éventuel retour à la ligne
	chomp($local_ligne);
       
	#On élimine un éventuel retour chariot hérité de Windows
	$local_ligne=~ s/\r$//;
       
	# Construction au moyen de la fonction split d'un tableau dont chaque élément a pour valeur un élément du motif recherché
	my @tokens=split(/ /,$local_ligne);
       
	#----------------------------- Construction du chemin XPATH-----------------------------------------------------------
	# Ce chemin correspond au premier nœud "élément" de l'arbre XML qui répond au motif cherché
	my $search_path="//element[contains(data[\@type=\"type\"],\"$tokens[0]\")]";
       
	# Initialisation du compteur pour la boucle de construction du chemin XPATH
	my $i=1;
	while ($i < $#tokens) {
        $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"$tokens[$i]\")]";
        $i++;
    }
    my $search_path_suffix="]";
       
    #L'opérateur x permet de répéter la chaine de caractère à sa gauche autant de fois que l'entier à sa droite,i.e. $i fois $search_path_suffix
    $search_path_suffix=$search_path_suffix x $i;
       
    # Construction du chemin XPATH final
    $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"".$tokens[$#tokens]."\")]".$search_path_suffix;
    print  "$search_path\n";
     
    #On renvoie le chemin XPATH et le tableau des éléments du motif
        return ($search_path,@tokens);
    }

sub extract_pattern{
    my $texte_ligne= shift @_;
	print "Le fichier contient ", $texte_ligne, "\n";
	my $tag_file= shift @_;
     
    # Appel de la fonction construit_XPath pour le motif lu à la ligne courante du fichier de motif
    my ($search_path,@tokens) = &construit_XPath($texte_ligne);
       
    #Définition du nom du fichier de résultats pour le motif en utilisant la fonction join
	my $tag_file1=$tag_file;
	$tag_file1=~s/SORTIE-treetagger *\/ *2013-treetagger-xml- *//g;
	$tag_file1=~s/\.xml//g;
	print "Le nom résultant est ", $tag_file1, "\n";
    my $match_file = $tag_file1."-".join('_', @tokens).".txt";
     
    # Ouverture du fichiers de résultats encodé en UTF-8
    open(MATCHFILE,">:encoding(UTF-8)", "extraction-motif_xmlToTxt/$match_file") or die "can't open $match_file: $!\n";
       
    #Création de l'objet XML::XPath pour explorer le fichier de sortie tree-tagger XML
    my $xp = XML::XPath->new( filename => $tag_file ) or die "big trouble";
       
    # Parcours des nœuds du ficher XML correspondant au motif, en utilisant la méthode findnodes
    # qui prend pour argument le chemin XPath construit précédemment
    # avec la fonction "construit_XPath"
    foreach my $noeud ( $xp->findnodes($search_path)) {
    #------------------- Initialisation du chemin XPATH------------------------------------------
	#Il correspond au nœud "data" contenant la forme correspondant au premier élément du motif
    # Ce chemin est relatif au premier nœud "élément" du bloc retourné et pointe sur le troisième nœud "data"
	#fils du nœud "élément" en l'identifiant par la valeur "string" de son attribut "type"
        my $form_xpath="";
        $form_xpath="./data[\@type=\"string\"]";
           
        # Initialisation du compteur pour la boucle d'extraction des formes correspondants
        # aux éléments suivants du motif
        my $following=0;
     
        # Recherche du nœud data contenant la forme correspondant au premier élément du motif avec la fonction "find" qui prend pour arguments:
        # 1. le chemin XPath relatif du nœud "data"
        # 2. le nœud en cours de traitement dans la boucle foreach
        # La fonction "find" retourne par défaut une liste de nœuds qui ne contient qu'un seul élément
		#qu'on récupère avec la fonction "get_node"
        # Le contenu textuel est imprimé à l'aide de la méthode string_value
        print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," ";
           
        # Boucle d'extraction des formes correspondants aux éléments suivants du motif
        # On descend dans chaque nœud élément du bloc
        while ( $following < $#tokens) {
            # Incrémentation du compteur $following de cette boucle d'extraction des formes
            $following++;
               
            # Construction du chemin XPath relatif du nœud "data" contenant la forme correspondant à l'élément suivant du motif
            my $following_elmt="following-sibling::element[".$following."]";           
            $form_xpath=$following_elmt."/data[\@type=\"string\"]";
     
            #   Impression du contenu textuel du noeud data contenant la forme correspondant à l'élément suivant du motif
            print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," ";
           
            # Incrémentation du compteur $following de cette boucle d'extraction des formes
            # $following++;
            }
        print MATCHFILE "\n";
        }
        # Fermeture du fichiers de motifs
        close(MATCHFILE);
    }


&recurseTousFics($racine);


#------------On va appliquer les fonctionnalités de la module XML::RSS dans la procédure récursive
sub recurseTousFics { 

    my $dossier=shift(@_);
    opendir(DOSSIER, $dossier) or die "can't open $dossier: $!\n";#FFFFFF
    my @files=readdir(DOSSIER);
    closedir(DOSSIER);
    print "liste des fichiers de $dossier : @files\n";
    print "Le chemin est le suivant : @files\n";
    foreach my $fic (@files){
	next if $fic =~ /^\.\.?$/; #print "On ne fait rien\n";
	next if $fic =~ /\.txt$/; #print "On ne fait rien\n";
	
	my $fic = $dossier."/".$fic;
	print "FICHIER : $fic \n";

	if (-d $fic){
	    &recurseTousFics($fic);
	}
	if (-f $fic){	
		print "Le bon fichier est\n", $fic;
		if (($fic=~/- *treetagger *- */) ) {
		print "On a trouvé le fichier ! \n", $fic;	
		#open(FILE, $file);
		
	    print "Traitement de :\n$fic\n";
		
		open(PATTERNSFILE, $patterns_file) or die "can't open $patterns_file: $!\n";
		 
		#Lecture du fichier contenant les motifs, un motif par ligne (par exemple : NOM ADJ)
		while (my $ligne = <PATTERNSFILE>) {
		print "La ligne est ", $ligne, "\n";
		# Appel à  la procédure d'extraction des motifs
			&extract_pattern($ligne, $fic);
		}
		# Fermeture du fichiers de motifs
		close(PATTERNSFILE);
	    
}

}
}
}
