
#include "fileManager.h"


array * fileManager_composeFiles( array * includedFilePaths ) {

	int FileNameCount 				= array_length( includedFilePaths );

	struct array * files			= array_new();

	for ( int i = 0; i < FileNameCount; ++i )
	{
		char * filePath						= array_get( includedFilePaths, i );

		struct file * fileInstance 			= file_new();

		fileInstance->filename 				= basename( text_copy( filePath ) );

		fileInstance->dirname	 			= dirname( text_copy( filePath ) );

		if( filePath[0] == 47 ) {

			memmove( filePath, filePath + 1, strlen( filePath ) );

		}

		fileInstance->path	 			= filePath;

		printf("basename:		%s\n\n", fileInstance->filename);

		fileInstance->source				= file_getSource( text_copy( fileInstance->path ) );

		array_add( files, fileInstance );

	}

	return files;

}

void fileManager_removeComments( array * files ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_removeComments( fileInstance );

	}

}

struct file * fileManager_getFileByPath( array * files, char * filePath ) {

	int fileCount 		= array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		//printf("compare:		%s	\n", fileInstance->path);

		if( strcmp( fileInstance->path, filePath ) == 0 ) {

			return fileInstance;

		}

	}

	return NULL;

}

bool array_includes( array * processedFiles, char * value ) {

	int count = array_length( processedFiles );

	for (int i = 0; i < count; ++i)
	{
		char * currentValue = array_get( processedFiles, i );

		if ( strcmp( value, currentValue ) == 0 )
		{

			return true;

		}
	}

	return false;

}
/*
void file_fixIncudes( struct file * currentFile, array * files, array * processedFiles  ) {

	int includeCount	= array_length( currentFile->includes );

	printf("entering %s     \n\n", currentFile->filename );

	for (int i = 0; i < includeCount; ++i)
	{

		struct include * includeInstance		= array_get( currentFile->includes, i );

		char * includePath						= file_getFileNameFromIncludeFixed( includeInstance->path );

		char * includeFileBaseName				= file_removeExtensionFromFileName( includePath );

		//char * includePath	= includeInstance->path;



			struct text * relativePath 	= text_new( currentFile->dirname );

			text_append( relativePath, "/" );

			text_append( relativePath, includeFileBaseName );


		

		char * resolvedPath	= resolve( relativePath->value );

		//printf("%s     \n", resolvedPath );

		struct file * fileInstance 				= fileManager_getFileByPath( files, resolvedPath );

		if( fileInstance != NULL ) {

			
			if( !array_includes( processedFiles, resolvedPath ) ) {

				printf("	adding %s to %s \n\n", resolve( relativePath->value ), currentFile->filename );


				includeInstance->enabled	= true;

				array_set( currentFile->includes, i, includeInstance );



				array_add( processedFiles, resolvedPath );

				file_fixIncudes( fileInstance, files, processedFiles );


			}


		}

	}

}

void fileManager_fixIncludes( array * files ) {

	printf("\n\n\n\n\n Fix includes \n\n\n\n");

	struct file * rootFile		= array_get( files, 0 );

	struct array * processedFiles	= array_new();

	printf(" rootFile:		%s\n\n\n", rootFile->filename);

	file_fixIncudes( rootFile, files, processedFiles );

	printf("\n\n");


	//exit( 0 );


}

*/

void fileManager_extractMacros( array * files ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_extractMacros( fileInstance );

	}

}

void fileManager_parseMacros( array * files ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		char * source 	= fileInstance->source;

		//file_parseMacros( fileInstance, files );

	}

}

void fileManager_extractClasses( array * files, struct application * applicationInstance ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		char * source 	= fileInstance->source;

		file_extractClasses( fileInstance );

	}

}

void fileManager_validateCurlyBrackets( array * files ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		char * source 	= fileInstance->source;

		text_validateCurlyBrackets( source );

	}

}

void fileManager_extractMethodsAndProperties( array * files ) {

	printf( "\n" );

	console_logColor( "\n\n\nDone.\n\n\n", "green" );

	console_logColor( "		2. Extract Methods and Properties.\n\n", "yellow" );

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_extractMethodsAndProperties( fileInstance );

	}

}

void fileManager_extractFunctions( array * files ) {

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_extractFunctions( fileInstance );

	}

}

void fileManager_parseMethods( array * files ) {

	printf( ANSI_COLOR_GREEN "\n\n\nDone.\n\n\n" ANSI_COLOR_RESET );

	printf( ANSI_COLOR_BRIGHT_YELLOW "		3. Parse Method bodies.\n\n" ANSI_COLOR_RESET);


	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		printf("%s.c:\n\n", fileInstance->path);

		printf("	Classes:\n\n");

		file_parseMethods( fileInstance, files );

		//printf("	Functions:\n\n");

	}

}

void fileManager_parseFunctions( array * files ) {

	printf( ANSI_COLOR_BRIGHT_YELLOW "		4. Parse Function bodies.\n\n" ANSI_COLOR_RESET);

	int fileCount = array_length( files );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		printf("file:	%s\n", fileInstance->filename);

		file_parseFunctions( fileInstance, files );

	}

}

void fileManager_extendClasses( array * files ) {

	int fileCount = array_length( files );

	printf( "\n" );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_extendClasses( fileInstance );

	}

}

void fileManager_extractTemplates( array * files ) {

	printf("\n\n\n\n\n\n					5. Extract templates\n\n\n\n\n\n\n");

	int fileCount = array_length( files );

	printf( "\n" );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_extractTemplates( fileInstance );

	}
	
}

void fileManager_instantiateTemplates( array * files ) {

	printf("\n\n\n\n\n\n						file_instanciateTemplates\n\n\n\n\n\n\n");

	int fileCount = array_length( files );

	printf( "\n" );

	for (int i = 0; i < fileCount; ++i)
	{

		struct file * fileInstance		= array_get( files, i );

		file_instanciateTemplates( fileInstance );

	}

}

int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
    int rv = remove(fpath);

    if (rv)
        perror(fpath);

    return rv;
}

void fileManager_removeFilesFromOutputDirectory( struct array * files, struct application * currentApplication ) {

	char * outputDirectory = currentApplication->output;

	printf("Delete directory: %s\n\n\n\n", outputDirectory);

	nftw( outputDirectory, unlink_cb, 64, FTW_DEPTH | FTW_PHYS );

	fileSystem_ensureDirectory( outputDirectory );

}

void fileManager_composeSourceAndHeaderFiles( struct array * files, struct application * currentApplication ) {

	int fileCount = array_length( files );



	for (int i = 0; i < fileCount; ++i)
	{
		struct file * fileInstance		= array_get( files, i );


		//printf("before crash:		%s\n\n\n\n", fileInstance->filename);

		file_compose( fileInstance, currentApplication );


	}





}

