import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

/**
 * Explore récursivement le disque dur et liste les fichiers.
 * @author Christian Mascart
 */
public class explorer
{
	/**
	 * @param args
	 */
	static int nbRep = 0,
				nbFiles = 0,
				nbLinks = 0,
				nbZero = 0; // Nombre de fichiers de taille zéro.
	static long 
				sommeTaille = 0, startTime = System.currentTimeMillis();
	static GregorianCalendar maDate = new GregorianCalendar();
	static DateFormat monFormat = new SimpleDateFormat("dd/MM/yyyy  HH:mm:ss z");
	
	public static void main(String[] args)
	{
		maDate.setTimeInMillis(startTime);
		
		PrintWriter pageWeb;
		try
		{
			pageWeb = new PrintWriter(new FileWriter("/home/disqueDur.htm"));
			pageWeb.println("<HTML>\n<HEAD><TITLE>L'exploration r&eacute;cursive du disque dur.</TITLE></HEAD>");
			pageWeb.println("<BODY>");
			pageWeb.println("D&eacute;but de l'exploration : " + monFormat.format(maDate.getTime()) + "<P>");
			
			fouiller (0, "/home/christian", pageWeb); //Répertoire racine de l'exploration.
			
			startTime = (System.currentTimeMillis() - startTime) / 1000;
			pageWeb.println("<HR width=50%>");
			pageWeb.println("J'ai visit&eacute;, en "+ startTime +" secondes, "+ nbRep + " r&eacute;pertoires, dans lesquels j'ai trouv&eacute; " + nbFiles + " fichiers d'une taille totale de " + sommeTaille + " octets.<P>");
			pageWeb.println("Nombre de fichiers vides : " + nbZero + "<BR>");
			pageWeb.println("</BODY></HTML>");
			
			pageWeb.close();
			System.out.println("J'ai visité, en "+ startTime +" secondes, "+ nbRep + " répertoires, dans lesquels j'ai trouvé " + nbFiles + " fichiers d'une taille totale de " + sommeTaille + " octets");
			if (nbZero > 0)
			{
				System.out.println("Nombre de fichiers vides : " + nbZero);
			}
			
			if (nbLinks > 0)
			{
				System.out.println("Liens : " + nbLinks);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	/**
	 * Proc&eacute;dure r&eacute;cursive d'exploration d'un r&eacute;pertoire
	 * */
	public static void fouiller (int profondeur, String pRep, PrintWriter pageWeb)
	{
		File a = new File(pRep);
		pageWeb.print("<FONT color=#0000FF>" + pRep +" </FONT>");
		System.out.print(pRep);

		if (a.exists())
		{
			File[] b = a.listFiles().clone(); // Pour ne pas la reconstruire à chaque lecture.
			pageWeb.println("<FONT color=#000000>" + b.length +" fichiers </FONT><BR>");
			// Recherche des fichiers
			long tailleRep = 0;
			System.out.println (" (" + b.length + " fichiers)");
			for (int i = 0; i < b.length; i++)
			{
				// Activer cette ligne pour mettre tous les fichiers visités à la date système
				// b[i].setLastModified(System.currentTimeMillis());
				if (isLink(b[i]))
				{
					nbLinks++;
					pageWeb.println("<FONT color=#FF0000>" + b[i].getName() + "</FONT> (lien)<BR>");
					System.out.println("Link " + b[i].getName());
				}
				else if (b[i].isFile())
				{
					if (b[i].length() == 0)
					{
						nbZero++;
						pageWeb.println("<FONT color=#AA0000>" + b[i].getName() + "</FONT> (vide)<BR>");
						System.out.println ("Zéro " + b[i].getName());
					}
					else
					{
						nbFiles++;
						//pageWeb.println("<FONT color=#000000>" + b[i].getName() + " ("+ b[i].length() +") </FONT><BR>");
						sommeTaille += b[i].length();
						tailleRep += b[i].length();
						//System.out.println(sommeTaille);
					}
				}
			}
			pageWeb.println("<FONT color=#808080>Volume : " + tailleRep + "</FONT><P>");
			// Ensuite, recherche des répertoires
			for (int i = 0; i < b.length; i++)
			{
				if (!isLink(b[i]) && b[i].isDirectory())
				{
					nbRep++;
					//System.out.println("Rep  " + pRep);
					//pageWeb.println("<FONT color=#0000FF> Rep  : " + b[i].getPath() + "</FONT><BR>");
					fouiller (profondeur + 1, pRep + "/" + b[i].getName(), pageWeb);
				}
			}
		}
		else
		{
			System.err.println(pRep + " n'existe pas.");
			pageWeb.println("<FONT color=#FF0000> Unk  : " + pRep + "</FONT><BR>");
		}
	}
	
	/**
	 * Les liens induisent des boucles infinies s'ils ciblent un parent<BR>
	 * Il ne faut pas les explorer.<BR>
	 * @param file Le fichier &agrave; tester
	 * @return true si c'est un lien
	 */
	public static boolean isLink(File file)
	{
		try
		{
			if (!file.exists())
				return (true);
			else
			{
				String cnnpath = file.getCanonicalPath();
				String abspath = file.getAbsolutePath();
				return (!abspath.equals(cnnpath));
			}
		}
		catch(IOException ex)
		{
			System.err.println(ex);
			return (true);
		}
	}
}
