#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <limits.h> // Pour définir PATH_MAX

#include "commun.h"
#include "ctrldate.h"
#include "copyfile.h"

#define false 0
#define true  1
#define bool int

extern bool CopyFile (char *szFileSrc, char *szFileDest);

char * cBufferFileExclus;
int iTailleFileExclus;
char * cBufferFileInclus;
int iTailleFileInclus;
bool bCopyMinus;

bool InitFileExclus (char* cBuffer, int iTaille)
{

	cBufferFileExclus = cBuffer;
	iTailleFileExclus = iTaille;
	return true;
}

bool InitFileInclus (char* cBuffer, int iTaille)
{
	cBufferFileInclus = cBuffer;
	iTailleFileInclus = iTaille;
	return true;
}

bool FileInclusExclus(char * szFile, int iTailleFile, char * cBufferFile)
{
	char szWarning[400];

	char * cBufferTrt;
	char resultat[1000];
	char Joker[1000];
	int iTaille, iTailleResult;
	bool bResult, bLigneNonVide, bJoker;
 
		iTaille = iTailleFile;
		cBufferTrt = cBufferFile;
 		do
		{		
			iTailleResult = sizeof(resultat);
            memset (resultat, 0, sizeof(resultat));
			bResult = ExtraireLigne(&cBufferTrt, resultat, &iTaille, &iTailleResult);

			if (bResult) // Il y a une ligne extraite;
			{
				bLigneNonVide = SupprimeEspaceAvAp (resultat, &iTailleResult);
				// Verifions que le fichier n'est pas exclus
				if (bLigneNonVide)
				{
					if ((resultat[0] == '.' && resultat[1] == '/') || (resultat[0] == '.' && resultat[1] == '.' && resultat[2] == '/'))
					{
						sprintf (szWarning, "D�sol�, mais cette version du code n'est pas pr�vu pour traiter . ou ..:\n      %s", resultat);
						GenereErreur (szWarning);
						return true;

					}
					if (NumEntries (resultat, '*') > 2)
					{
						sprintf (szWarning, "D�sol�, mais cette version du code n'est pas pr�vu pour traiter plusieurs *:\n      %s", resultat);
						GenereErreur (szWarning);
						return true;
					}

					if (NumEntries (resultat, '?') > 1)
					{
						sprintf (szWarning, "D�sol�, mais cette version du code n'est pas pr�vu pour traiter les ?:\n      %s", resultat);
						GenereErreur (szWarning);
						return true;
					}

					if (NumEntries (resultat, '*') == 1)
					{
/*						printf ("Pas de joker !\n");*/
						if (strcmp (szFile, resultat) == 0)
						{ // Ok, Fichier inclus !
							return true;
						}
						// Sinon, on va continuer sur la ligne suivante !
					}
					else
					{
						bJoker = false;
						// Joker !
						// Traitement de la premi�re partie:
						FnctEntry (resultat, 1, '*', Joker);
						if (strlen(Joker) > 0)
						{
							if (memcmp (szFile, Joker, strlen(Joker)) == 0)
								bJoker = true;
							else
								bJoker = false;
						}
						else
							bJoker = true;

						if (bJoker)
						{
						// Traitement de la deuxi�me partie:
							FnctEntry (resultat, 2, '*', Joker);
						//	printf (Joker);
							if (strlen(Joker) > 0)
							{
								if (memcmp (szFile + strlen(szFile) - strlen(Joker), Joker, strlen(Joker)) == 0)
									bJoker = true;
								else
									bJoker = false;
							}
							else
								bJoker = true;
						}

						if (bJoker)
						{
							return true;
						}

						// Sinon, v�rification sur la ligne suivante !
					}
				}
            }
		} while (bResult);
		return false; // Non trouv� dans la liste
}

bool FileInclus(char * szFile)
{
	if (iTailleFileInclus != 0 && cBufferFileInclus != 0) // Il existe une section file inclus
		return FileInclusExclus (szFile, iTailleFileInclus, cBufferFileInclus);
	else
		return true;
}

bool FileExclus(char * szFile)
{
// c'est con, mais c'est pratiquement la fonction FileInclus !!!
	if (iTailleFileExclus != 0 && cBufferFileExclus != 0) // Il existe une section file exclus
		return FileInclusExclus (szFile, iTailleFileExclus, cBufferFileExclus);
	else
		return false;
}

bool GenereDest (char * szDir)
{
	// Attention fichier relatif commençant par / ...
	int iCpt = NumEntries (szDir, '/'), iCptTrt;
	char szDirTrt [1000];
	char szDirTemp [1000];
	struct stat bufstat;

	szDirTemp[0] = 0;
	if (iCpt > 1)
	{
		iCptTrt = 1;
		do
		{
			strcpy (szDirTrt, szDir);
			FnctEntry (szDirTrt, iCptTrt, '/', szDirTrt);
			strcat (szDirTemp, "/");
			strcat (szDirTemp, szDirTrt);

			if (mkdir(szDirTemp, S_IRUSR | S_IWUSR | S_IXUSR ) == 0)
			{
				chmod (szDirTemp, S_IRUSR | S_IWUSR | S_IXUSR );
			}
			else
			{
				stat(szDirTemp, &bufstat);

				if (!S_ISDIR(bufstat.st_mode))
				{ 
					return false;
				}
				// Sinon, il existe, tant mieux !
			}
		}while (++iCptTrt < iCpt);
		return true;
	}
	else
		return true;
}

bool TraiterFichier(char* szFile, char * szPathInit, char* szDirDest)
{
	char szErreur[400];
	char szFileRelatif[1000];
	char szFileDest[1000];

	if (FileInclus(szFile))
	{
		if (!FileExclus(szFile))
		{
				if (CtrlDateFile(szFile))
				{

					// G�n�ration d'un chemin relatif
					memcpy (szFileRelatif, szFile + strlen (szPathInit), strlen (szFile) - strlen (szPathInit));
					*(szFileRelatif + strlen (szFile) - strlen (szPathInit)) = 0;

				// Construction du chemin destination complet 
						strcpy (szFileDest, szDirDest);
						strcat (szFileDest, szFileRelatif);
/*						printf (szFileDest);
						printf ("\n");*/
				// G�n�rer le repertoire destination.
					GenereDest(szFileDest);
/*					if (SHCreateDirectoryEx(NULL, &szFileDest, NULL) != ERROR_SUCCESS)*/
						// Et enfin la copie du fichier !
						copyfileok();
						sprintf (szErreur, "Copie du fichier %s", szFile);
						GenereErreur (szErreur);
					    return CopyFile (szFile, szFileDest);
/*					else
					{
						sprintf (szErreur, "--> Incident lors de la cr�ation de l'arborescence du fichier %s dans le r�pertoire temporaire %s", szFile, szFileDest);
						GenereErreur (szErreur);
						return false;
					}*/
				}
				else
					return true;

		}
		else
			return true;
	}
	return true;
}
