#include <stdio.h>
#include <iostream> 
#include <string>
#include <dirent.h>
#include <cstdlib>
#include "TStringList.h"

#ifndef _GestionFichiers_
#define _GestionFichiers_

void Executer(String commande);
void Executer(String commande, TStringList *retour);

bool FileExists(String fichier);
bool DirectoryExists(String repertoire);
void RemoveDir(String repertoire);
void ForceDirectories(String repertoire);
void DeleteFile(String fichier);
bool RenameFile(String nom_avant, String nom_apres, bool ecraser_si_existe);

void SSHExecuter(String connexion, String commande);
void SSHExecuter(String connexion, String commande, TStringList *retour);

bool SSHFileExists(String connexion, String fichier);
bool SSHDirectoryExists(String connexion, String repertoire);
void SSHRemoveDir(String connexion, String repertoire);
void SSHForceDirectories(String connexion, String repertoire);
void SSHDeleteFile(String connexion, String fichier);
bool SSHRenameFile(String connexion, String nom_avant, String nom_apres, bool ecraser_si_existe);

String ExtractFileName(String chemin_complet);
String ExtractFilePath(String nom_fichier);
String ExtractFileDir(String nom_fichier);

int FileSize(String nom_fichier);


void ListerFichiers(TStringList *liste, String NomRep, bool SousRep);
void ListerFichiers(TStringList *liste, String NomRep, String extension, bool SousRep);

int  EspaceDisqueDistant(String serveur_distant, String disque_partition);

void LectureOptions(String nom_fichier, String option_cherchee, TStringList *options);
void LectureOptions(String nom_fichier, String option_cherchee, String *option);

String RepertoireApplication();


//---------------------------------------------------------------------------
bool FileExists(String fichier)
{
bool sortie;
FILE *fp = fopen (fichier.c_str(), "r");

if (fp == NULL)
    sortie=false;
else
{
	sortie=true;
    fclose(fp);
}
return sortie;
}

//---------------------------------------------------------------------------
bool DirectoryExists(String repertoire)
{
//return !chdir(repertoire.c_str());
return(opendir(repertoire.c_str()));
}

//---------------------------------------------------------------------------
void RemoveDir(String repertoire)
{
	String commande;
	commande = "rm -rf "+repertoire;
	
	system(commande.c_str());
}

//---------------------------------------------------------------------------
void ForceDirectories(String repertoire)
{
	String commande;
	String rep1;
	
	TStringList *rep = new TStringList();
	explode(rep, repertoire, "/");
	if(rep->Count>0)
	{
		if(rep->Strings[0]!="~")
			rep1="/";
	}
	for(int i=0;i<rep->Count;i++)
	{
		rep1=rep1+rep->Strings[i]+"/";
		if(!DirectoryExists(rep1))
		{
			commande = "mkdir "+rep1;
			system(commande.c_str());
		}
	}
	delete rep;
}

//---------------------------------------------------------------------------
void DeleteFile(String fichier)
{
	String commande;
	
	if(FileExists(fichier))
	{
		commande = "rm -f "+fichier;
		system(commande.c_str());
	}
}

//---------------------------------------------------------------------------
bool RenameFile(String nom_avant, String nom_apres, bool ecraser_si_existe)
{
	String commande;
	bool retour;
	TStringList *sortie = new TStringList();
	
	retour = false;
	if(FileExists(nom_avant))
	{
		if(FileExists(nom_apres))
		{
			if(ecraser_si_existe)
			{
				DeleteFile(nom_apres);
				Executer("mv \""+nom_avant+"\" \""+nom_apres+"\"", sortie);
				if(sortie->Count==0)	// S'il n'y a pas eu de message d'erreur
					retour = true;
			}
		}
		else
		{
			Executer("mv \""+nom_avant+"\" \""+nom_apres+"\"", sortie);
			if(sortie->Count==0)	// S'il n'y a pas eu de message d'erreur
				retour = true;
		}
	}
	
	delete sortie;
	
	return retour;
}


//---------------------------------------------------------------------------
bool SSHFileExists(String connexion, String fichier)
{
bool retour;
TStringList *sortie;

retour = false;
sortie = new TStringList();
SSHExecuter(connexion, "ls "+fichier, sortie);
if(sortie->Count>=1)
	if(StrReplace(sortie->Strings[0], "\n", "")==fichier)
		retour = true;
delete sortie;

return retour;
}

//---------------------------------------------------------------------------
bool SSHDirectoryExists(String connexion, String repertoire)
{
TStringList *sortie;
bool retour;

retour = true;
sortie = new TStringList();
cout << repertoire << endl;
SSHExecuter(connexion, "ls "+repertoire, sortie);
if(sortie->Count>=1)
	if((AnsiPos("Aucun", sortie->Strings[0])!=0)||(AnsiPos("No such", sortie->Strings[0])!=0))
		retour = false;
delete sortie;

return(retour);
}

//---------------------------------------------------------------------------
void SSHRemoveDir(String connexion, String repertoire)
{
	SSHExecuter(connexion, "rm -rf "+repertoire);
}

//---------------------------------------------------------------------------
void SSHForceDirectories(String connexion, String repertoire)
{
 	String rep1;
	
	TStringList *rep = new TStringList();
	explode(rep, repertoire, "/");
	if(rep->Count>0)
	{
		if(rep->Strings[0]!="~")
			rep1="/";
	}
	for(int i=0;i<rep->Count;i++)
	{
		rep1=rep1+rep->Strings[i]+"/";
		//if(!SSHDirectoryExists(connexion, rep1))
			Executer(connexion+" mkdir "+rep1);	
	}
        Executer(connexion+" mkdir "+repertoire);
	delete rep;
}

//---------------------------------------------------------------------------
void SSHDeleteFile(String connexion, String fichier)
{
	if(SSHFileExists(connexion, fichier))
		SSHExecuter(connexion, "rm -f "+fichier);
}

//---------------------------------------------------------------------------
bool SSHRenameFile(String connexion, String nom_avant, String nom_apres, bool ecraser_si_existe)
{
	bool retour;
	TStringList *sortie = new TStringList();
	
	retour = false;
	if(SSHFileExists(connexion, nom_avant))
	{
		if(SSHFileExists(connexion, nom_apres))
		{
			if(ecraser_si_existe)
			{
				SSHDeleteFile(connexion, nom_apres);
				SSHExecuter(connexion, "mv \""+nom_avant+"\" \""+nom_apres+"\"", sortie);
				if(sortie->Count==0)	// S'il n'y a pas eu de message d'erreur
					retour = true;
			}
		}
		else
		{
			SSHExecuter(connexion, "mv \""+nom_avant+"\" \""+nom_apres+"\"", sortie);
			if(sortie->Count==0)	// S'il n'y a pas eu de message d'erreur
				retour = true;
		}
	}
	
	delete sortie;
	
	return retour;
}

//---------------------------------------------------------------------------
String ExtractFileName(String chemin_complet)
{
	String nom_fichier;
	
	nom_fichier = chemin_complet;
	while(StrPos("/", nom_fichier)!=-1)
		nom_fichier = SubString(nom_fichier, StrPos("/", nom_fichier)+1, StrLength(nom_fichier));
	
	return nom_fichier;
}

//---------------------------------------------------------------------------
String ExtractFilePath(String nom_fichier)
{
	String path, car;

	path = nom_fichier;
	car=SubString(path, strlen(nom_fichier.c_str()), 1);
	while((car!="/")&&(StrLength(path)!=0))
	{
		path = SubString(path, 1, strlen(path.c_str())-1);
		car=SubString(path, strlen(path.c_str()), 1);
	}
	
	return path;
}

//---------------------------------------------------------------------------
String ExtractFileDir(String nom_fichier)
{
	return ExtractFilePath(nom_fichier);
}

//---------------------------------------------------------------------------
int FileSize(String nom_fichier)
{
	TStringList *sortie;
	String str;
	int taille=0;
	
	if(FileExists(nom_fichier))
	{
		sortie = new TStringList();
		Executer("ls -s "+nom_fichier, sortie);
		if(sortie->Count==1)
		{
			str = Trim(StrReplace(sortie->Strings[0], nom_fichier, ""));
			if(is_number(str))
				valueOf(str, taille);
		}
		
		delete sortie;
	}
	
	return taille;
}

//---------------------------------------------------------------------------
void Executer(String commande, TStringList *retour)
{
FILE *pp;
char buf[256];

retour->Clear();
pp=popen(commande.c_str(), "r");
if (pp)
{
	while (fgets(buf, sizeof buf, pp))
		retour->Add(buf);
}
pclose(pp);
}

//---------------------------------------------------------------------------
void Executer(String commande)
{
FILE *pp;
pp=popen(commande.c_str(), "r");
pclose(pp);
}


//---------------------------------------------------------------------------
void SSHExecuter(String connexion, String commande, TStringList *retour)
{
String fichier_temp;
FILE *pp;

fichier_temp = "temp"+ Now().FormatString("yymmddhhnnss");

retour->Clear();
commande = "ssh -tv "+connexion+" "+commande+" > " + fichier_temp;
pp=popen(commande.c_str(), "r");
pclose(pp);
if(!FileExists(fichier_temp))
	cout << "Erreur lors de l'execution de SSHExecuter ! Impossible de creer le fichier " << fichier_temp << endl;
else
{
	retour->LoadFromFile(fichier_temp);
	DeleteFile(fichier_temp);
}
}

//---------------------------------------------------------------------------
void SSHExecuter(String connexion, String commande)
{
FILE *pp;
commande = "ssh -tq "+connexion+" "+commande;
pp=popen(commande.c_str(), "r");
pclose(pp);
}

//---------------------------------------------------------------------------
void ListerFichiers(TStringList *liste, String NomRep, bool SousRep)
{
String commande,rep, nom_fichier;
int i,j;
TStringList *temp = new TStringList();
TStringList *temp1 = new TStringList();

liste->Clear();

if(SubString(NomRep, strlen(NomRep.c_str()), 1)!="/")
	rep = NomRep+"/";
else
	rep = NomRep;

if(SousRep==false) // Juste le repertoire specifie
	commande = "ls -l "+rep;
else
	commande = "ls -lR "+rep;

Executer(commande, temp);
for(i=0;i<temp->Count;i++)
{
	explode(temp1, temp->Strings[i], " ");
	
	if((temp1->Count==1)&&(SousRep))	// Si c'est une ligne indiquant le repertoire courant
		rep=StrReplace(StrReplace(temp1->Strings[0], ":", "/"), "\n", "");
	
	if(temp1->Count>2)
	{
		// 1ere colonne : on verifie que ce n'est pas un repertoire
		if(SubString(temp1->Strings[0], 0, 1)!="d")
		{
			// on ne garde que le nom du fichier (la derniere colonne)
			nom_fichier = StrReplace(temp1->Strings[temp1->Count-1], "\n", "");
			liste->Add(StrReplace(rep+nom_fichier, "//", "/"));
		}
	}
}


delete temp1;
delete temp;
}

//---------------------------------------------------------------------------
void ListerFichiers(TStringList *liste, String NomRep, String extension, bool SousRep)
{
String commande,rep, nom_fichier;
int i,j,longueur;
TStringList *temp = new TStringList();
TStringList *temp1 = new TStringList();

longueur=strlen(extension.c_str());

liste->Clear();

if(SubString(NomRep, strlen(NomRep.c_str()), 1)!="/")
	rep = NomRep+"/";
else
	rep = NomRep;

if(SousRep==false) // Juste le repertoire specifie
	commande = "ls -l "+rep;
else
	commande = "ls -lR "+rep;

Executer(commande, temp);
for(i=0;i<temp->Count;i++)
{
	explode(temp1, temp->Strings[i], " ");
	
	if((temp1->Count==1)&&(SousRep))	// Si c'est une ligne indiquant le repertoire courant
		rep=StrReplace(StrReplace(temp1->Strings[0], ":", "/"), "\n", "");
	
	if(temp1->Count>2)
	{
		// 1ere colonne : on verifie que ce n'est pas un repertoire
		if(SubString(temp1->Strings[0], 0, 1)!="d")
		{
			// on ne garde que le nom du fichier (la derniere colonne)
			nom_fichier = StrReplace(temp1->Strings[temp1->Count-1], "\n", "");
			
			// on verifie que le fichier porte bien l'extension choisie
			if(longueur!=0)
			{
				if(strlen(nom_fichier.c_str())>=longueur)
					if(SubString(nom_fichier, strlen(nom_fichier.c_str())+1-longueur,longueur)==extension)
						liste->Add(StrReplace(rep+nom_fichier, "//", "/"));
			}
			else
				liste->Add(StrReplace(rep+nom_fichier, "//", "/"));
		}
	}
}


delete temp1;
delete temp;
}

//---------------------------------------------------------------------------
int EspaceDisqueDistant(String serveur_distant, String disque_partition)
{
	TStringList *retour = new TStringList();
	TStringList *temp = new TStringList();
	String commande;
	int i;
	int taille;
	
	taille=0;
	commande = "ssh "+serveur_distant+" df -k "+disque_partition;
	Executer(commande, retour);
	
	if(retour->Count>1)
	{
		explode(temp, retour->Strings[1], " ");
		if(temp->Count==6)
			valueOf(temp->Strings[3], taille);
	}
	
	delete retour;
	delete temp;
	
	return taille;
}

//---------------------------------------------------------------------------
// Retourne le repertoire de l'application
String RepertoireApplication()
{
/*	String rep;
	char buf[500];
	getcwd(buf, 500); 
	rep = buf;
	return rep+"/"; */
	String rep;
	rep = "";
	TStringList *sortie = new TStringList();
	Executer("pwd", sortie);
	if(sortie->Count!=0)
	{
		if(StrPos("/",sortie->Strings[0])!=-1)
		{
			rep = sortie->Strings[0];
			rep = StrReplace(rep, "\n", "");
			rep = StrReplace(rep, "\r", "");
			rep = rep + "/";
		}
	}
	delete sortie;
	return rep;
}

//---------------------------------------------------------------------------
void LectureOptions(String nom_fichier, String option_cherchee, TStringList *options)
{
int i;
TStringList *fichier_options = new TStringList();
if(FileExists(nom_fichier))
{
	fichier_options->LoadFromFile(nom_fichier);
	if(options==NULL)
		options = new TStringList();
	else
		options->Clear();

	i=0;

	while((i<fichier_options->Count)&&(StrPos(option_cherchee, fichier_options->Strings[i])==-1))
		i++;

	if(i<fichier_options->Count)
            if(StrPos(option_cherchee, fichier_options->Strings[i])!=-1)
   	    {
		i++;
		while((i<fichier_options->Count)&&(strlen(fichier_options->Strings[i].c_str())>1))
		{
			options->Add(fichier_options->Strings[i]);
			i++;
		}
	    }
}
else
	cout << "ERREUR : fichier d'option "+nom_fichier+" non trouve." << endl;
delete fichier_options;
}

//---------------------------------------------------------------------------
void LectureOptions(String nom_fichier, String option_cherchee, String *option)
{
int i;
TStringList *fichier_options = new TStringList();
if(FileExists(nom_fichier))
{
	fichier_options->LoadFromFile(nom_fichier);
	i=0;
	while((i<fichier_options->Count)&&(StrPos(option_cherchee, fichier_options->Strings[i])==-1))
		i++;
	if(i<fichier_options->Count)
            if(StrPos(option_cherchee, fichier_options->Strings[i])!=-1)
  	    {
		i++;
	        *option = fichier_options->Strings[i];
	    }
}
else
	cout << "ERREUR : fichier d'option "+nom_fichier+" non trouve." << endl;

delete fichier_options;
}

#endif
