
import java.io.*;
import java.util.*;

public class LogRemover {

	public final String NEWLINE="\r\n";
	
	boolean isAddPreStatement = false;
	boolean isRecoveryMode = false;
	boolean isVerbose = false;
	boolean isApplyIndentation = false;
	
	int totalFiles;
	int failureFiles;
	long processedEvents;
	
	
	public LogRemover()
	{
		totalFiles = 0;
		failureFiles = 0;
		processedEvents= 0;
	}
	
	public void setAddPreStatement(boolean sw)
	{
		isAddPreStatement = sw;
	}
	
	public void setRecoveryMode(boolean sw)
	{
		isRecoveryMode = sw;
	}
	
	public void setVerbose(boolean sw)
	{
		isVerbose = sw;
	}
	
	public void setApplyIndentation(boolean sw)
	{
		isApplyIndentation = sw;
	}
	
	public void process(File dir)
	{			
		if( isRecoveryMode ) isAddPreStatement = false;
		
		if( !dir.exists())
		{
			if( isVerbose ) System.out.println("[Error] File Not Found : " + dir.getName());
			return;
		}
		
		if( dir.isDirectory() )				
			traverse(dir);			
		else 
			doJob(dir);
	}
	
	private void traverse(File dir)
	{
		File[] list = dir.listFiles();
		
		for( File file : list)
		{
			if( file.isDirectory() ) traverse( file);
			if( file.getName().toLowerCase().endsWith(".c")) doJob(file);
		}		
	}
	
	public void doJob(File srcFile) 
	{	
		totalFiles ++;
		
		if( isVerbose ) System.out.print("["+totalFiles + "]" + srcFile.getName());
		
		int replaced = 0;
		
		String replaceRegExp = "(event_log\\s*\\(\\s*[a-zA-Z_0-9\\[\\]]+\\s*),.*";
		String replaceRegExp2 = "$1\\);";
		
		try{
			File tempFile = new File("temp_"+srcFile.getName());
			
			BufferedReader br = new BufferedReader(new FileReader(srcFile));
			BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile));
			
			String line;
			
			boolean isIfDefStarted = false;
			
			
			while( (line = br.readLine()) != null)
			{			
				if( line.matches("^.*#ifdef EVENT_DEBUG.*"))
				{
					isIfDefStarted = true;
				}
				
				boolean isLongEventStatement = line.matches("^\\s*event_log.*,.*;.*");
				String indentationStr ="";
				
				if( isLongEventStatement )
				{
					indentationStr = line.substring(0, line.indexOf("event_log") );
				}
				
				if( isIfDefStarted )
				{
					/*
					 * ÀÌ¹Ì #ifdef EVENT_DEBUG ·Î ½ÃÀÛµÈ °æ¿ì¿¡´Â
					 * AddPreStatement ¸ðµåÀÎ °æ¿ì´Â ±×´ë·Î Ãâ·ÂÇÏ°í
					 * ¸¸¾à AddPreStatement ¸ðµå°¡ ¾Æ´Ñ °æ¿ì, Áï
					 * #ifdef ¾øÀÌ  ´Ü¼øÈ÷ EventLog¸¦ »èÁ¦ÇÏ´Â °æ¿ì´Â
					 * #ifdef °¡ Á¤ÀÇµÈ ºÎºÐÀ» ÇÔ²² »èÁ¦ÇÏµµ·Ï ÇÑ´Ù.
					 */
					if( isAddPreStatement )	
					{						
						bw.write(line + NEWLINE);
					} else {						
						if( isLongEventStatement )
						{
							if(isRecoveryMode)
								bw.write( line + NEWLINE);
							else
								bw.write( line.replaceFirst(replaceRegExp,replaceRegExp2) + NEWLINE);
							
							replaced ++;
						}
					}					
				} else {  /* IfDef ºí·°ÀÌ ¾Æ´Ñ °æ¿ì */
					
					if( isLongEventStatement )
					{
						if( isAddPreStatement )
						{
							if(isApplyIndentation) bw.write(indentationStr);
							bw.write("#ifdef EVENT_DEBUG" + NEWLINE);
							bw.	write(line + NEWLINE);
							
							if(isApplyIndentation) bw.write(indentationStr);
							bw.write("#else" + NEWLINE);
							bw.write( line.replaceFirst(replaceRegExp,replaceRegExp2) + NEWLINE);
							
							if(isApplyIndentation) bw.write(indentationStr);
							bw.write("#endif" + NEWLINE);
							replaced++;
						} else {
							if( isRecoveryMode )
							{
								bw.write(line + NEWLINE);
							}else{
								bw.write( line.replaceFirst(replaceRegExp,replaceRegExp2) + NEWLINE);
								replaced++;
							}
						}
					} else {
						bw.write(line + NEWLINE);
					}					
				}
								
				if( line.matches("^.*#endif.*"))
				{
					isIfDefStarted = false;
				}
				
			}
			
			bw.close();
			br.close();
			
			if( replaced > 0 )
			{
			
				String destFileName = srcFile.getAbsolutePath();
				srcFile.delete();
				
				tempFile.renameTo(new File(destFileName));
			
			} else {
				tempFile.delete();				
			}
			
			if( isVerbose ) System.out.println( "  ..." + replaced + " replaced. Success");
			
			
			
		}catch(Exception e)
		{
			e.printStackTrace();
			failureFiles++;
			if( isVerbose ) System.out.println( "FAILED!!");
		} 
		
		processedEvents += replaced;
	}
	
	
	
	public static void showUsage()
	{
		System.out.println("Event Log Remover (build 003)");
		System.out.println("Usage:");
		System.out.println(" options file file ...\n");
		System.out.println("[OPTIONS]");
		System.out.println(" -v    verbose mode");
		System.out.println(" -a    add preprocessing statements");
		System.out.println(" -d    delete event log message");
		System.out.println(" -r    restore original event log");
		System.out.println(" -i    apply indentation");
		System.out.println("");
		System.out.println("2008.12.15\nHyun-Kyu Shin\n");		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Vector<String> fileNameList = new Vector<String>();
		
		LogRemover lr = new LogRemover();
		lr.setRecoveryMode(false);
		lr.setVerbose(false);
		lr.setApplyIndentation(false);
		
		boolean isModeDefined = false;
		
		for( String arg : args)
		{
			if(arg.equals("-a"))
			{
				lr.setAddPreStatement(true);
				isModeDefined = true;
			}else if( arg.equals("-d"))
			{
				lr.setAddPreStatement(false);
				isModeDefined = true;
			}else if( arg.equals("-r"))
			{
				lr.setRecoveryMode(true);
				isModeDefined = true;
			}else if( arg.equals("-v"))
			{
				lr.setVerbose(true);
			}else if( arg.equals("-i"))
			{
				lr.setApplyIndentation(true);
			}else fileNameList.add(arg);
			
		}
		
		if( !isModeDefined || fileNameList.size()==0)
		{
			showUsage();
			System.exit(0);				
		}
		
	
		long duration = System.currentTimeMillis();
		for( String fileName : fileNameList)
		{
			try{
				lr.process(new File(fileName));
			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		duration = System.currentTimeMillis() - duration;
	
		
		System.out.println("\n\n>>Processing Summary");
		System.out.println("Total Files: " + lr.totalFiles);
		System.out.println("Failed Files: " + lr.failureFiles);
		System.out.println("ProcessedEvents: " + lr.processedEvents);
		System.out.println("Elapsed Time: " + duration + " msec");
		
		
	}

}
