/* modified by Yijun Yu on Feb 17, 2005*/

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.File;
import java.util.StringTokenizer;

/*
   (c) 2004-2005 John W. Stamey, Bryan T. Saunders, and Matthew Cameron.
    This program is licensed under the GNU General Public License.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

public class AOPHP {

	public static void main(String[] args) {
		String phpInPath = args[0];
		String phpInFile = args[1];
		String phpOutFile = args[2];
		try{
			System.out.println("Checking if AOPHP Required..");
			String temp = "";
			BufferedReader phpIn = new BufferedReader(new FileReader(phpInFile));
			String php = "";
			while(phpIn.ready()){
				php += phpIn.readLine() + "\n";
			}
			phpIn.close();
			File dir = new File(phpInPath);
			String files[] = dir.list();
			for (int i=0; i<files.length; i++) {
				File f = new File(dir, files[i]);
				if (!files[i].endsWith(".aspect")) continue;
				// Open AOPHP File
				//System.out.println("Opening Aspect PHP File..");
				String aophpFile;
				//int start = php.indexOf("//AOPHP(")+8;
				//aophpFile = php.substring(start,php.indexOf(")",start));
				//aophpFile = phpInPath + aophpFile; // Fix
				aophpFile = f.getAbsolutePath(); // Fix
				BufferedReader aophpIn = new BufferedReader(new FileReader(aophpFile));
				
				// Make Symbol Table
				System.out.println("Creating Advice Table..");
				int startPos;
				int endPos;
				String function;
				String code = "";
				AOPHPTable aotable = new AOPHPTable();
				while(aophpIn.ready()){
					temp = aophpIn.readLine();
					//if(temp.contains("AOPHP_before"))\{
					if(temp.indexOf("AOPHP_before")>=0){
						// Get the Function
						startPos = temp.indexOf("AOPHP_before(")+13;
						endPos = temp.indexOf(")",startPos);
						function = temp.substring(startPos,endPos);
						// Get the Code
						temp = "";
						//while(!temp.contains("#"))\{
						while(temp.indexOf("#")<0){
							code += temp;
							temp = aophpIn.readLine();
						}
						aotable.addAdvice(new Symbol(function,"before",code));
						code = "";
					//\}else if(temp.contains("AOPHP_after"))\{
					}else if(temp.indexOf("AOPHP_after")>=0){
						startPos = temp.indexOf("AOPHP_after")+12;
						endPos = temp.indexOf(")",startPos);
						function = temp.substring(startPos,endPos);
						temp = "";
						//while(!temp.contains("#"))\{
						while(temp.indexOf("#")<0){
							code += temp;
							temp = aophpIn.readLine();
						}
						aotable.addAdvice(new Symbol(function,"after",code));
						code = "";
					//\}else if(temp.contains("AOPHP_around"))\{
					}else if(temp.indexOf("AOPHP_around")>=0){
						startPos = temp.indexOf("AOPHP_around")+13;
						endPos = temp.indexOf(")",startPos);
						function = temp.substring(startPos,endPos);
						temp = "";
						//while(!temp.contains("#"))\{
						while(temp.indexOf("#")<0){
							code += temp;
							temp = aophpIn.readLine();
						}
						aotable.addAdvice(new Symbol(function,"around",code));
						code = "";
					}
				}
				System.out.println("Advice Table Complete");
				aophpIn.close();
				//aotable.printTable();
				
				// Add Aspects to PHP File
				System.out.println("Weaving Aspects into PHP File..");
				//phpIn = new BufferedReader(new FileReader(phpInFile));
				PrintWriter phpOut = new PrintWriter(new FileWriter(phpOutFile));
				temp = "";
				code = "";
				StringTokenizer st = new StringTokenizer(php, "\n");
				//while(phpIn.ready()) \{
				String result = "";
				while(st.hasMoreTokens()){
					//temp = phpIn.readLine();
					temp = st.nextToken();
					// Find and Print any Before Advice for this Line
					code = aotable.findAdvice(temp,"before");
					if(code != null){
						//phpOut.println(code);
						result += code;
					}
					
					// Find and Print and Around Advice
					// Print Previous Line of Code if No Advice was Present
					code = aotable.findAdvice(temp,"around");
					if(code != null){
						// Is Around Advice
						//phpOut.println(code);
						result += code;
					}else{
						// No Around Advice
						//phpOut.println(temp);
						result += temp + "\n";
					}
					
					// Find and Print and After Advice for this Line
					code = "";
					code = aotable.findAdvice(temp,"after");
					if(code != null){
						//phpOut.println(code);
						result += code;
					}
				}
				System.out.println("Writting new PHP Code..");
				//phpOut.close();
				php = result;
			} 
			System.out.println("AOPHP Not Required, Using Original Code...");
			PrintWriter phpOut = new PrintWriter(new FileWriter(phpOutFile));
			//while(blah.ready()){
			phpOut.println(php);
			//}
			phpOut.close();
			System.out.println("Sending Code to PHP Parser..");
		}catch(Exception e){
			System.err.println("AOPHP ERROR");
			e.printStackTrace();
		}
	}
}