/***********************************************************************
 * 
 *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 *  Author: Juan Carlos Luciani <jluciani@novell.com>
 *  
 ***********************************************************************/

import java.io.*;
import java.util.*;

/**
 * Summary description for DeleteFile
 */
public class DeleteFile
{
	final static int ERROR_NO_ERROR						= 0;
	final static int ERROR_INVALID_NUMBER_OF_PARAMS		= -1;
	final static int ERROR_BAD_FILE_PARAM				= -2;
	final static int ERROR_IO_EXCEPTION					= -3;
	final static int ERROR_FILE_PARAM_REPEATED			= -4;
	final static int ERROR_FILTER_PARAM_REPEATED		= -5;
	final static int ERROR_UNKNOWN_PARAMETER			= -6;
	final static int ERROR_MISSING_FILE_PARAM			= -7;
	final static int ERROR_FILTER_ON_NON_DIRECTORY		= -8;
	final static int ERROR_BAD_PROPERTY_FILE_PARAM		= -9;;

	final static String FILE_KEY		= "file=";
	final static String FILTER_KEY		= "filter=";

	RandomAccessFile	raf;
	int					rc;
	String				sFile;
	String				sFilter;

	public static void main(String[] args)
	{
		DeleteFile p = new DeleteFile(args);
		System.exit(p.rc);
	}

	DeleteFile(String[] args)
	{
		rc = ERROR_NO_ERROR;
		sFile = null;
		sFilter = null;

		try
		{
			raf = new RandomAccessFile(new File("c:\\test8.log"), "rw");
			raf.seek(raf.length());

			// Process the arguments
			if (ERROR_NO_ERROR == (rc = processArgs(args)))
			{
				rc = doDelete();
			}

		}
		catch (IOException e)
		{
			rc = ERROR_IO_EXCEPTION;
		}
		finally
		{
			try
			{
				log(rc);
				raf.close();
			}
			catch (Exception e1)
			{
			}
		}
	}

	int processArgs(String[] argsOld)
	{
		String sProperties;
		File fileInstallDir = null;
		int iEquals;
		String sKey;
		String sValue;
		int iOld;
		int i;
		String args[] = new String[argsOld.length];
		int iNew;

		log("Original arg count " + argsOld.length);
		for (i = 0; i < argsOld.length; i++)
		{
			log("Arg " + i + " = " + argsOld[i] + "\r\n");
		}

		// Validate the number of parameters
		if (args.length < 1)
		{
			return ERROR_INVALID_NUMBER_OF_PARAMS;
		}

		iNew = -1;
		for (iOld = 0; iOld < argsOld.length; iOld++)
		{
			if (0 <= argsOld[iOld].indexOf("="))
			{
				iNew++;
				args[iNew] = argsOld[iOld];
				for (i = iOld + 1; i < argsOld.length && (-1 == argsOld[i].indexOf("=")); i++)
				{
					args[iNew] += " " + argsOld[i];
				}
			}
		}

		log("New arg count " + args.length);
		for (i = 0; i < args.length; i++)
		{
			if (null == args[i])
			{
				continue;
			}

			log("arg[" + i + "] = " +args[i]);

			// is this the file to delete param?
			if (args[i].startsWith(FILE_KEY))
			{
				// Have we already processed a file paramter?
				if (null != sFile)
				{
					return ERROR_FILE_PARAM_REPEATED;
				}

				// Make sure it is more the param tag
				if (args[i].length() <= FILE_KEY.length())
				{
					return ERROR_BAD_FILE_PARAM;
				}

				sFile = args[i].substring(FILE_KEY.length()).trim();
			}

			// is this the filter param?
			else if (args[i].startsWith(FILTER_KEY))
			{
				// Have we already processed a filter paramter?
				if (null != sFilter)
				{
					return ERROR_FILTER_PARAM_REPEATED;
				}

				// Make sure it is more than the param tag
				if (args[i].length() <= FILTER_KEY.length())
				{
					return ERROR_BAD_PROPERTY_FILE_PARAM;
				}

				sFilter = args[i].substring(FILTER_KEY.length()).trim();
			}

			// Handle additional parameters
			else
			{
				return ERROR_UNKNOWN_PARAMETER;
			}
		}

		// Make sure we got a file
		if (null == sFile)
		{
			return ERROR_MISSING_FILE_PARAM;
		}

		// Note: the filter parameter is optional, if present the file is assumed to be a directory

		return ERROR_NO_ERROR;
	}

	int doDelete()
	{
		File file = new File(sFile);

		log("Attempt to delete: " + sFile);

		// If the file is already gone - we are happy.
		if (!file.exists())
		{
			log("File did not exist: " + sFile);
			return ERROR_NO_ERROR;
		}

		// If a filter was passed in but the file is not a directory...
		if (null != sFilter)
		{
			log("there is a filter:  + sFilter");

			// The file is not a directory - we wont try to apply the filter
			if (!file.isDirectory())
			{
				log("file is not a directory");
				return ERROR_FILTER_ON_NON_DIRECTORY;
			}

			// The file is a directory
			else
			{
				log("file is a directory");
				// Delete the children that match the template
				deleteFiles(file);

				// Attempt to delete the directory
				deleteDirectory(file);
			}
		}

		else
		{
			if (!file.isDirectory())
			{
				log("Delete file: " + sFile);
				file.delete();
			}

			else
			{
				deleteDirectory(file);
			}
		}

		return ERROR_NO_ERROR;
	}

	void deleteFiles(File file)
	{
		File fileDelete;
		int i;

		log("attempting to delete file");

		// Get the children of this directory
		File[] rgFile = file.listFiles(
			new FileFilter()
			{
				public boolean accept(File f)
				{
					if (null == sFilter) return true;
					log("file " + f.getName() + " matches filter " + sFilter + " : " + (-1 != f.getName().indexOf(sFilter))) ;
					return (-1 != f.getName().indexOf(sFilter)); 
				}
			});

		log(file.getAbsolutePath() + " has " + rgFile.length + " children that match the filter: " + sFilter);

		// Attempt to delete each child file
		for (i = 0; i < rgFile.length; i++)
		{
			if (rgFile[i].isDirectory())
			{
				deleteDirectory(rgFile[i]);
			}
			else
			{
				log("Delete file: " + rgFile[i].getAbsolutePath());
				rgFile[i].delete();
			}
		}
	}

	void deleteDirectory(File file)
	{
		File fileDelete;
		int i;

		log("Delete directory: " + file.getAbsolutePath());

		// Get the children of this directory
		File[] rgFile = file.listFiles();

		log(file.getAbsolutePath() + " has " + rgFile.length + " children");

		// Delete empty child directories
		for (i = 0; i < rgFile.length; i++)
		{
			if (rgFile[i].isDirectory())
			{
				deleteDirectory(rgFile[i]);
			}
		}

		// Delete this directory if it is empty
		rgFile = file.listFiles();
		if (rgFile.length == 0)
		{
			log("Delete file: " + file.getAbsolutePath());
			file.delete();
		}
	}


	void log(int err)
	{
		log(err, null);
	}

	void log(int err, String s)
	{
		String sMessage = "";

		switch (err)
		{
			case ERROR_NO_ERROR:
				sMessage = "No error";
				break;
			case ERROR_INVALID_NUMBER_OF_PARAMS:
				sMessage = "Invalid number of parameters: 1 expected";
				break;
			case ERROR_BAD_FILE_PARAM:
				sMessage = "Bad file parameter";
				break;
			case ERROR_FILE_PARAM_REPEATED:
				sMessage = "File parameter repeated";
				break;
			case ERROR_FILTER_PARAM_REPEATED:
				sMessage = "Filter parameter repeated";
				break;
			case ERROR_UNKNOWN_PARAMETER:
				sMessage = "Unknown parameter: ";
				break;
			case ERROR_MISSING_FILE_PARAM:
				sMessage = "Missing file parameter";
				break;
			case ERROR_FILTER_ON_NON_DIRECTORY:
				sMessage = "Filter parameter of non-directory file";
				break;
			case ERROR_BAD_PROPERTY_FILE_PARAM:
				sMessage = "Bad property file parameter";
				break;
			default:
				sMessage = "Unknown error: " + err;
				break;
		}

		if (null != s)
		{
			sMessage = sMessage + s;
		}
		log(sMessage);
	}

	void log(String s)
	{
		try
		{
			raf.writeUTF(this.getClass().getName() + ": " + s + "\r\n");
		}
		catch (IOException ioe)
		{
		}
	}
}