#!/usr/bin/perl


#Crea un hash contenente tutti i gruppi di classi e i relativi id
#HashIDClasse{Gruppi di classi}{id assegnati}


my $File_it_en = $ARGV[0];;


open (HYPER, "$File_it_en");

my %HashClasseID;

my $id = 1;
while (<HYPER>) {
	
	chomp;
	@line = split; 
	
	$GruppoClassi = $line[0];
	$GruppoHyperonimi = $line[1];
	
	#HASH ID | CLASSI -> Hyperonimi 
	
	$HashClasseID{$id}{$GruppoClassi} = $GruppoHyperonimi;
	$id++;
		
}

close(HYPER);

#**************************************************************************************************************

#Crea un hash contenente tutti i gruppi di classi e i relativi id
#HashIDClasse{Gruppi di classi}{id assegnati}


my $File_en_en = $ARGV[1];;


open (HYPER, "$File_en_en");

my %HashHyperonimiID;

$id = 1;
while (<HYPER>) {
	
	chomp;
	@line = split; 
	
	$GruppoHyperonimi = $line[0];
	$GruppoTop = $line[1];
	
	#HASH ID | HYPERONIMI - > Top Node 
	
	$HashHyperonimiID{$id}{$GruppoHyperonimi} = $GruppoTop;
	$id++;
	
}

close(HYPER);



#**************************************************************************************************************

#Crea un hash contenente tutti gli hyperonimi (filler), le teste, le frequenze e i relativi id
#HashFillerTestaFrequenzaID{Filler}{Testa}{Frequenza}{id}


my $Rep_input = $ARGV[2];;

my %HashFillerTestaFrequenzaID;

open (TFF, "$Rep_input");

$id = 1;
while (<TFF>) {
	chomp;
	
	@line = split;
	$Testa = $line[0];
	$Filler = substr ($line[1], 0, -2); #Rimuove -s dai fillers
	$Frequenza = $line[2];
	
	#HASH FILLER | TESTA | Frequenza - > ID 
	
	$HashFillerTestaFrequenzaID{$Filler}{$Testa}{$Frequenza} =  $id;
	$id++;
	
}
close(TFF);




#**************************************************************************************************************

#Crea un hash contenente tutti l'id della classe (file matiten) e l'id del nodo cui punta (file matenen)
#HashIDclasseIDhyper{ID classe}{ID hyperonimo puntato da quella classe}
#Verifico i match tra i filler e le classi
my %HashIDclasseIDhyper;
my %HashIDClasseHyperonimiTestaFreq;
foreach $Filler (sort keys %HashFillerTestaFrequenzaID) {#matrep

	foreach $IDClasse (sort keys %HashClasseID) {#matiten
		
		foreach $GruppoClassi (sort keys %{$HashClasseID{$IDClasse}}) {#matiten
	
			if($GruppoClassi=~ m/^$Filler;|;$Filler$|;$Filler;|^$Filler$/){ #Verifica se in ogni gruppo di classi è contenuto il filler
		
				foreach $Testa (sort keys %{$HashFillerTestaFrequenzaID{$Filler}}) {#matrep
				
					foreach $Frequenza (sort keys %{$HashFillerTestaFrequenzaID{$Filler}{$Testa}}) {#matrep
					
						my $IDFiller = $HashFillerTestaFrequenzaID{$Filler}{$Testa}{$Frequenza};
						if (exists $HashIDclasseIDhyper{$IDClasse}{$GruppoClassi}{$Testa}) {
							$HashIDclasseIDhyper{$IDClasse}{$GruppoClassi}{$Testa} += $Frequenza;
						}else{
							$HashIDclasseIDhyper{$IDClasse}{$GruppoClassi}{$Testa} = $Frequenza;
						}
						
					}
					#Calcolo il numero di gruppi di hyperonimi collegati alla coppia (GruppoClassi|Testa)
					$HashIDClasseHyperonimiTestaFreq{$IDClasse}{$HashClasseID{$IDClasse}{$GruppoClassi}}{$Testa} = $HashIDclasseIDhyper{$IDClasse}{$GruppoClassi}{$Testa} / NumeroHyperonimi($GruppoClassi);
				
				}
					
			}
			
		}
		
	}
	
}
#*****************************************************************************************
# FINE PRIMA PARTE
#*****************************************************************************************

my %HashIDHyperHyperTestaFrequenza;
#Contiene idHyper | GruppoHyperonimi | Testa - > Frequenza
foreach $idClasse (sort keys %HashIDClasseHyperonimiTestaFreq) {
	foreach $GruppoHyperonimi (sort keys %{$HashIDClasseHyperonimiTestaFreq{$idClasse}}) {
		foreach $Testa (sort keys %{$HashIDClasseHyperonimiTestaFreq{$idClasse}{$GruppoHyperonimi}}) {
			foreach $idHyperonimo(sort keys %HashHyperonimiID) {
				foreach $Hyperonimo(sort keys %{$HashHyperonimiID{$idHyperonimo}} ) {
					if($GruppoHyperonimi eq $Hyperonimo){	
						my $FrequenzaPrecedente = $HashIDClasseHyperonimiTestaFreq{$idClasse}{$GruppoHyperonimi}{$Testa};
						$HashIDHyperHyperTestaFrequenza{$idHyperonimo}{$GruppoHyperonimi}{$Testa}=$FrequenzaPrecedente;
					}
				}
			}
			
		}
	}
}

my %HashHyperTestaFrequenza2;
#Contiene GruppoHyperonimi | Testa - > Frequenza
#Faccio questo per compattare 
foreach $idHyper (sort keys %HashIDHyperHyperTestaFrequenza) {
	foreach $GruppoHyperonimi (sort keys %{$HashIDHyperHyperTestaFrequenza{$idHyper}}) {
		foreach $Testa (sort keys %{$HashIDHyperHyperTestaFrequenza{$idHyper}{$GruppoHyperonimi}}) {
			if (exists $HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa}) {
				$HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} += $HashIDHyperHyperTestaFrequenza{$idHyper}{$GruppoHyperonimi}{$Testa};
			}else{
				$HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} = $HashIDHyperHyperTestaFrequenza{$idHyper}{$GruppoHyperonimi}{$Testa};
			}		
		}
	}
}
#Stampo l'hash prima del nuovo aggiornamento
my $File_out_ris1 = "Passo1_ris.txt";
open (RIS, ">>$File_out_ris1");
#print "\n\n------------- PASSO_1 : da it a en > TESTA - IPERONIMO - FREQUENZA------------- \n";
foreach $GruppoHyperonimi (sort keys %HashHyperTestaFrequenza2) {
	foreach $Testa (sort keys %{$HashHyperTestaFrequenza2{$GruppoHyperonimi}}) {
		#print $Testa . "\t" . $GruppoHyperonimi . " \t".$HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} . "\n";
		print RIS $Testa . "\t" . $GruppoHyperonimi . " \t".$HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} . "\n";		
	}
	
}		
close(RIS);

#Prelevo i top node collegati
my %HashTopNodeCollegati;
foreach $GruppoHyperonimi (sort keys %HashHyperTestaFrequenza2) {
	foreach $Testa (sort keys %{$HashHyperTestaFrequenza2{$GruppoHyperonimi}}) {
		$HashTopNodeCollegati{$GruppoHyperonimi}{$Testa} = elencoTopNodeCollegati($GruppoHyperonimi);
	}
}

my %HashTopNodeTestaFrequenza;
#Contiene  Gruppo top node | Testa | Gruppo Hyperonimi | Frequeza
foreach $GruppoHyperonimi (sort keys %HashHyperTestaFrequenza2) {
	foreach $Testa (sort keys %{$HashHyperTestaFrequenza2{$GruppoHyperonimi}}) {
		my @arrayTopNodeCollegati = split("-----",$HashTopNodeCollegati{$GruppoHyperonimi}{$Testa});
		foreach my $TopNodeCollegato(@arrayTopNodeCollegati){
			if($TopNodeCollegato ne ""){
				if (exists $HashTopNodeTestaFrequenza{elencoTopNodeCollegati($GruppoHyperonimi)}{$Testa}) {
					$HashTopNodeTestaFrequenza{elencoTopNodeCollegati($GruppoHyperonimi)}{$Testa} += $HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} / NumeroTopNode($GruppoHyperonimi);
				}else{
					$HashTopNodeTestaFrequenza{elencoTopNodeCollegati($GruppoHyperonimi)}{$Testa} = $HashHyperTestaFrequenza2{$GruppoHyperonimi}{$Testa} / NumeroTopNode($GruppoHyperonimi);
				}
			}
		}
	}
}

# AGGIORNA
# - Se il generico topnode X di HashTopNodeTestaFrequenza è un iperonimo nell'hash iniziale HashHyperonimiID (ovvero compare anche a sinistra)
#   allora la frequenza di ciascun TopNode(X) si aggiorna come  frequenza X / numeroTopNode(X) presi da HashHyperonimiID
my %HashTopNodeTestaFrequenza2; # Contiene anche i top node a destra di questo hash splittati con le diverse teste e le frequenze divise 
								# Es: Testa | T1-T2...-Tn | F -> diventa Testa T1 F/n , Testa T2 F/n ... Testa Tn F/n  
foreach $GruppoTopNode (sort keys %HashTopNodeTestaFrequenza) {
	foreach $Testa (sort keys %{$HashTopNodeTestaFrequenza{$GruppoTopNode}}) {
		my @arrayTopNodeCollegati = split("-----",$GruppoTopNode);
		foreach my $TopNodeCollegato(@arrayTopNodeCollegati){
			if($TopNodeCollegato ne ""){
				if($#arrayTopNodeCollegati>0){
					$HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato} = $HashTopNodeTestaFrequenza{$GruppoTopNode}{$Testa}/($#arrayTopNodeCollegati+1);
				}else{
					$HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato} = $HashTopNodeTestaFrequenza{$GruppoTopNode}{$Testa};
				}
			}
		}
	}
}

my @elencoCompletoTopNodeSX;
my $indice = 0;
foreach $Testa (sort keys %HashTopNodeTestaFrequenza2) {
	foreach $TopNode (sort keys %{$HashTopNodeTestaFrequenza2{$Testa}}) {
		$elencoCompletoTopNodeSX[$indice] = $TopNode;
		$indice++;
	}
}

foreach my $TopNode (@elencoCompletoTopNodeSX){
	foreach $Testa (sort keys %HashTopNodeTestaFrequenza2) {
			
			if(NumeroTopNode($TopNode)>0){#Top node è un hyperonimo
				my @arrayTopNodeCollegatiTopNode = split("-----",elencoTopNodeCollegati($TopNode));
				
				foreach my $TopNodeCollegato(@arrayTopNodeCollegatiTopNode){
					if(exists $HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato}){
						$HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato} += $HashTopNodeTestaFrequenza2{$Testa}{$TopNode} / NumeroTopNode($TopNode);
					}else{
						$HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato} = $HashTopNodeTestaFrequenza2{$Testa}{$TopNode} / NumeroTopNode($TopNode);
					}
				}
				
			}
	
		}
}

my $File_out_risTOT = "Passo2_risTOT.txt";
open (RISTOT, ">>$File_out_risTOT");
#print "\n\n------------- PASSO_2 : da en a tutti gli iperonimi > TESTA - NODO - FREQUENZA-------------\n";
foreach $Testa (sort keys %HashTopNodeTestaFrequenza2) {
	foreach $TopNodeCollegato (sort keys %{$HashTopNodeTestaFrequenza2{$Testa}}) {
		if($HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato}>0){
			#print "\n " . $Testa  . "\t" . $TopNodeCollegato . " \t". $HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato};
			print RISTOT "\n " . $Testa  . "\t" . $TopNodeCollegato . " \t". $HashTopNodeTestaFrequenza2{$Testa}{$TopNodeCollegato};
		}
	}
}

#FUNZIONI DI SERVIZIO
sub NumeroTopNode{
	$GruppoHyperonimi = @_[0];
	my $NumeroTopNode = 0;
	foreach $ID (sort keys %HashHyperonimiID) {
		if(exists $HashHyperonimiID{$ID}{$GruppoHyperonimi}){
			$NumeroTopNode++;
		}
	}
	return $NumeroTopNode;
}
sub elencoTopNodeCollegati{
	$GruppoHyperonimi = @_[0];
	my $ElencoTop = "";
	foreach $ID (sort keys %HashHyperonimiID) {
		if(exists $HashHyperonimiID{$ID}{$GruppoHyperonimi}){
			$ElencoTop =$ElencoTop.$HashHyperonimiID{$ID}{$GruppoHyperonimi}. "-----";
		}
	}
	return $ElencoTop;
}
sub NumeroHyperonimi{
	$GruppoClassi = @_[0];
	my $NumeroHyperonimi = 0;
	foreach $ID (sort keys %HashClasseID) {
		if(exists $HashClasseID{$ID}{$GruppoClassi}){
			$NumeroHyperonimi++;
		}
	}
	return $NumeroHyperonimi;
}

sub getTime () {
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
     $year += 1900;
     $mon += 1;
     my $retval = sprintf("$year\-%02d\-%02d %02d:%02d:%02d",$mon,$mday,$hour,$min,$sec);
     return $retval;
 }
 
