/* ***********************IMPORTANT *********************************************
 *  Copyright (C) 2004-2007 Thierry Lagarde <tlagarde@users.sourceforge.net>
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License.
 *
 *
 *                      ********************
 *
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *
 *                      ********************
 *
 *
 * You are highly encouraged to send your changes to <tlagarde@users.sourceforge.net>
 * for possible incorporation into the main distribution.
 * By sending these changes to <tlagarde@users.sourceforge.net>,
 * it is assumed that you are offering <tlagarde@users.sourceforge.net>
 * the unlimited, non-exclusive right to reuse, modify, and relicense the code.
 *
 *
 *                      ********************
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **************************************************************************************/
#include <gtk/gtk.h>
#include "Commun.h"
#include "Initialisation_Com.h"
#include "../Declaration_Constante.h"
#include "../Debug.h"
#include "../Settings_Port.h"
#include "../Settings.h"
#include "../Settings_Signature.h"
#include "../Add_Network_Subnet.h"
#include "../Interface/Combo.h"
#include "../Interface/Wizard_Interface_Add_Network.h"
#include "../Interface/Wizard_Callbacks_Add_Network.h"
#include "../Interface/Wizard_Interface.h"
#include "../Interface/Wizard_Callbacks.h"
#include "../Interface/Erreur_Interface.h"
#include "../Gconf.h"
#include "../Restoration_Agent.h"
#include "Communication.h"
#include "../Animation.h"
#include "../Settings_Restore.h"
#include "../Interface/Root_Interface.h"
#include "../Interface/Demarrage_Interface.h"
#include "../Interface/Maemo.h"
#include "../Macro.h"

void Efface_Toute_Interface_Combo (void)
{
	Efface_Combo (combobox_Select_Interface);
}


void Demande_Arret_Agent (struct Struct_Liste_Reseau *Reseau)
{
	struct struct_Demande_Arret_Agent Message;

	bzero (&Message, sizeof (struct struct_Demande_Arret_Agent));
	Message.ID_Reseau = Reseau->Id_Reseau;
	Communication_Envoie_Donnee (Reseau->Pid_Agent, DEMANDE_ARRET_AGENT, (gpointer *) & Message, sizeof (Message), Reseau);
}


void Recuperation_Message_Agent (gpointer * Donnee)
{
	struct struct_Retour_Message *Message = NULL;

	ERROR_if (Donnee == NULL);
	Message = (struct struct_Retour_Message *) Donnee;
	debug_printf (Message->ID_Reseau, Message->Type_message, Message->File, Message->Fonction, Message->Line, Message->Message);
	Recuperation_Nb_Octet_Recu (sizeof (struct struct_Retour_Message), Recupere_Pointeur_Structure_Reseau (Message->ID_Reseau));
}



void Recuperation_Retour_Critique_Agent (gpointer * Donnee)
{
	struct struct_Retour_Erreur_Critique *Message_Critique = NULL;
	gchar    *Message = NULL;
	
	ERROR_if (Donnee == NULL);
	Message_Critique = (struct struct_Retour_Erreur_Critique *) Donnee;
	if (Message_Critique->Type_message == D_SEG_FAULT)
		Message = g_strdup_printf ("Segmentation fault : Invalid memory reference\n\nautoscan-network-daemon has terminated unexpectedly \nThread : %s\nObjet : %s", Message_Critique->Thread, Message_Critique->Objet);
	else
		Message = g_strdup_printf ("Error : autoscan-network-daemon has terminated unexpectedly \nThread : %s\nObjet : %s", Message_Critique->Thread, Message_Critique->Objet);
	Info_Message_Critique = g_strdup(Message_Critique->Info);
	Affiche_Win_Erreur();
	gtk_label_set_text (GTK_LABEL (label_Erreur), Message);
	MYFREE (Message);
}




void Recuperation_Nouvelle_Interface (gpointer * Donnee)
{
	struct struct_Nouvelle_Interface *Interface = NULL;

	ERROR_if (Donnee == NULL);
	if (!AutoRestore) {
		Interface = (struct struct_Nouvelle_Interface *) Donnee;
		Ajoute_Interface_Combo (Interface->Interface, Interface->Ip);
	}
}

void Recuperation_Liste_Interface_Fini (gpointer * Donnee)
{
	ERROR_if (Donnee == NULL);
	if (AutoRestore) {
#ifndef         __MAEMO
		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.8);
#else
		gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.8);
#endif
		Agent_Initialiser = TRUE;	
	}
	else {
		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 1);
		gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Initialisation : completed ");
		gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_Select_Interface), 0);
		gtk_label_set_text (GTK_LABEL (label_Initialize), "Select the network Interface");
		gtk_widget_hide (progressbar_Initialize);
		gtk_widget_show (combobox_Select_Interface);
		Wizard_Bouton_Avancer_Post = Wizard_Bouton_Post_Add_Network_Page5;
  		Wizard_Bouton_Avancer = Wizard_Bouton_Add_Network_Page5;
		Wizard_Bouton_Enable();
		refresh ();
		Agent_Initialiser = TRUE;
	}
	refresh ();
}

void Demande_Liste_Interface (void)
{
	struct struct_Demande_Liste_Interface Message;

	bzero (&Message, sizeof (struct struct_Demande_Liste_Interface));
	Communication_Envoie_Donnee (Pid_Agent_Initialisation, DEMANDE_LISTE_INTERFACE, (gpointer *) & Message, sizeof (Message), NULL);
}


void Initialisation_Agent_Ajout_Sous_Reseau_Autorise (void)
{
	struct Struct_Subnet *Subnet = NULL;
	struct struct_Ajout_Reseau_Privee Message;
	guint     Nb_Objet_Liste, i;

	bzero (&Message, sizeof (struct struct_Ajout_Reseau_Privee));
	Nb_Objet_Liste = g_list_length (GList_Subnet);
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Envoie a l'agent la liste des subnet (%d)", Nb_Objet_Liste);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Subnet = g_list_nth_data (GList_Subnet, i);
		Message.Masque = Subnet->Masque;
		Message.A = Subnet->A;
		Message.B = Subnet->B;
		Message.C = Subnet->C;
		Communication_Envoie_Donnee (Pid_Agent_Initialisation, AJOUT_RESEAU_PRIVEE, (gpointer *) & Message, sizeof (Message), NULL);
	}
}


void Initialisation_Agent_Ajout_Sous_Reseau_Autorise_Restoration (void)
{
	struct Struct_Subnet *Subnet = NULL;
	struct struct_Ajout_Reseau_Privee Message;
	guint     Nb_Objet_Liste, i;

	bzero (&Message, sizeof (struct struct_Ajout_Reseau_Privee));
	Nb_Objet_Liste = g_list_length (Subnet_Restauration);
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Envoie a l'agent  Restoration la liste des subnet (%d)", Nb_Objet_Liste);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Subnet = g_list_nth_data (Subnet_Restauration, i);
		Message.Masque = Subnet->Masque;
		Message.A = Subnet->A;
		Message.B = Subnet->B;
		Message.C = Subnet->C;
		Communication_Envoie_Donnee (Pid_Agent_Initialisation, AJOUT_RESEAU_PRIVEE, (gpointer *) & Message, sizeof (Message), NULL);
	}
}


void Initialisation_Agent_Ajout_Port (void)
{
	struct Struct_Liste_Port *Port = NULL;
	struct struct_Ajout_Port Message;
	guint     Nb_Objet_Liste, i;

	bzero (&Message, sizeof (struct struct_Ajout_Port));
	Nb_Objet_Liste = g_list_length (Settings->GList_Port);
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Envoie a l'agent la liste des ports (%d)", Nb_Objet_Liste);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Port = g_list_nth_data (Settings->GList_Port, i);
	
		if (Port->Port_Pere == NULL) {
		
			Message.Num_Port = Port->Num_Port;
			Message.Serveur = (Port->Type == SERVEUR);
			Communication_Envoie_Donnee (Pid_Agent_Initialisation, AJOUT_PORT, (gpointer *) & Message, sizeof (Message), NULL);
		
		}
	}
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fin : Envoie a l'agent la liste des ports (%d)", Nb_Objet_Liste);
}


void Reception_Version_Agent (gpointer * Donnee)
{
	struct struct_Agent_Version *Agent_Version = NULL;
	struct struct_Demande_Arret_Agent Message;
	gchar *Message_Erreur = NULL;

	ERROR_if (Donnee == NULL);
	Agent_Version = (struct struct_Agent_Version *) Donnee;
	Pid_Agent_Initialisation = Agent_Version->pid;
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Pid de l'agent : (%d)", Pid_Agent_Initialisation);
	if ((strcmp (Agent_Version->Version, VERSION_AGENT) == 0) 
#ifdef  __CHECK_STRUCT_ENABLE
		&& (Agent_Version->Taille_Struct==TAILLE_ALL_STRUCTURE)
#endif
		){
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Version AutoScan_Agent : OK");
		if (AutoRestore) {
#ifndef         __MAEMO
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.1);
#else
			gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.1);
#endif
		}
		else
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Ports list");
		refresh ();
	
		Initialisation_Agent_Ajout_Port ();
		if (AutoRestore) {
#ifndef         __MAEMO
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.2);
#else
			gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.2);
#endif
		}
		else {
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 0.4);
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Interface List");
		}
		refresh ();
	
		Demande_Liste_Interface ();
		if (Wizard_Restauration_Fichier_Xml || (AutoRestore)) {
			if (AutoRestore) {
#ifndef         __MAEMO
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.5);
#else
				gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.5);
#endif
				Restoration_Agent (Fichier_En_Cours_Restoration);
			}
			else {
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 0.6);
				gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Restore equipment");
				Restoration_Agent (Wizard_Chemin_Fichier_Xml);
			}
			refresh ();
			if (AutoRestore) {
#ifndef         __MAEMO
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 0.6);
#else
				gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.6);
#endif
			}
			else {
				gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 0.8);
				gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Subnet list");
			}
			refresh ();
			Initialisation_Agent_Ajout_Sous_Reseau_Autorise_Restoration ();
		}
		else {
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 0.8);
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), "Subnet list");
			refresh ();
			Initialisation_Agent_Ajout_Sous_Reseau_Autorise ();
		}
	}
	else {
#ifdef  __CHECK_STRUCT_ENABLE
		if (Agent_Version->Taille_Struct!=TAILLE_ALL_STRUCTURE)
			Message_Erreur = "[FAILED] Size of struct";
		else
#endif	
			Message_Erreur = "[FAILED] Version check";
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%d  %d   [%s]  [%s]",Agent_Version->Taille_Struct,TAILLE_ALL_STRUCTURE,Agent_Version->Version, VERSION_AGENT);
		if (AutoRestore) {
#ifndef         __MAEMO
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Demarrage), 1);
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Demarrage), Message_Erreur);
#else
			gtk_progress_bar_set_fraction_maemo (banner_maemo_Demarrage, 0.1);
			gtk_progress_bar_set_text_maemo (banner_maemo_Demarrage, Message_Erreur);
#endif
			refresh ();
			sleep (3);
		}
		else {
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar_Initialize), 1);
			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar_Initialize), Message_Erreur);
		}
		
		bzero (&Message, sizeof (struct struct_Demande_Arret_Agent));
		Message.ID_Reseau = ID_RESEAU_PAS_INITIALISE;
		Communication_Envoie_Donnee (Pid_Agent_Initialisation, DEMANDE_ARRET_AGENT, (gpointer *) & Message, sizeof (Message), NULL);
	}
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Reception_Version_Agent : fini");

}


void Demande_Demarrage_Agent (gint ID_Reseau,gchar *Nom_Reseau, gchar * Interface, gchar * Communaute_Snmp, gboolean Autoriser_A_Scanner)
{
	struct struct_Demarrage_Agent Message;


	bzero (&Message, sizeof (struct struct_Demarrage_Agent));
	Message.ID_Reseau = ID_Reseau;
	strcpy (Message.Interface, (char *) Interface);
	debug_printf (INTERFACE, D_INFO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Interface : [%s]", Message.Interface);
	if ((strlen(Nom_Reseau)+1)>TAILLE_NOM_ID_STRUCT_NOUVELLE_INTERFACE)
		strncpy(Message.nom,Nom_Reseau,TAILLE_NOM_ID_STRUCT_NOUVELLE_INTERFACE);
	else
		strcpy(Message.nom,Nom_Reseau);	
	strcpy (Message.Communaute_Snmp, (char *) Communaute_Snmp);
	Message.Nb_Thread_Max = Lecture_Gconf_Int (INT_THREAD_MAX);
	Message.Autoriser_A_Scanner = Autoriser_A_Scanner;
	Message.Niveau_Debugage = Debug;
	Message.Normal_Mode = Lecture_Gconf_Boolean (BOOL_NORMAL_MODE);
	Message.Ip_Dynamic = Lecture_Gconf_Boolean (BOOL_IP_DYNAMIC);
	Communication_Envoie_Donnee (Pid_Agent_Initialisation, DEMARRAGE_AGENT, (gpointer *) & Message, sizeof (Message), NULL);
}
