/**
 *
 * Copyright 2005 Jeremy Rayner
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **/
package org.codehaus.groovy.antlr.java;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.codehaus.groovy.antlr.AntlrASTProcessor;
import org.codehaus.groovy.antlr.SourceBuffer;
import org.codehaus.groovy.antlr.UnicodeEscapingReader;
import org.codehaus.groovy.antlr.java.Java2GroovyConverter;
import org.codehaus.groovy.antlr.java.JavaLexer;
import org.codehaus.groovy.antlr.java.JavaRecognizer;
import org.codehaus.groovy.antlr.parser.GroovyLexer;
import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
import org.codehaus.groovy.antlr.treewalker.*;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;

import antlr.collections.AST;

public class Java2GroovyMain {

	public static void main(String[] args) {
		try{
			Options options = new Options();
			PosixParser cliParser = new PosixParser();
			CommandLine cli = cliParser.parse(options, args);
            String[] filenames = cli.getArgs();
            if( filenames.length == 0 ) {
            	System.err.println("Needs at least one filename");
            }
            List filenameList = Arrays.asList(filenames);
            Iterator i = filenameList.iterator();
            while (i.hasNext()) {
            	String filename = (String) i.next();
            	File f = new File(filename);
            	String text = DefaultGroovyMethods.getText(f);
            	System.out.println(convert(text, true, true));
            }
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	public static String convert(String input) throws Exception{
		return convert(input, false, false);
	}
	
	public static String convert(String input,boolean withHeader, boolean withNewLines) throws Exception{
        JavaRecognizer parser = getJavaParser(input);
        String[] tokenNames = parser.getTokenNames();
        parser.compilationUnit();
        AST ast = parser.getAST();
        // modify the Java AST into a Groovy AST
        modifyJavaASTintoGroovyAST(tokenNames, ast);
        String[] groovyTokenNames = getGroovyTokenNames(input);
        // groovify the fat Java-Like Groovy AST
        groovifyFatJavaLikeGroovyAST(ast, groovyTokenNames);

        // now output        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Visitor visitor = new SourcePrinter(new PrintStream(baos),groovyTokenNames, withNewLines);
        AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);

        traverser.process(ast);
        
        String header = "";
        if (withHeader) {
	        header = "/*\n" +
	        				"  Automatically Converted from Java Source \n" +
	        				"  \n" +
	        				"  by java2groovy v0.0.1   Copyright Jeremy Rayner 2007\n" +
	        				"  \n" +
	        				"  !! NOT FIT FOR ANY PURPOSE !! \n" +
	        				"  'java2groovy' cannot be used to convert one working program into another" +
	        				"  */\n\n";
        }
        return header + new String(baos.toByteArray());
    }

	/**
	 * @param ast
	 * @param groovyTokenNames
	 */
	private static void groovifyFatJavaLikeGroovyAST(AST ast, String[] groovyTokenNames) {
		Visitor groovifier = new Groovifier(groovyTokenNames);
        AntlrASTProcessor groovifierTraverser = new PreOrderTraversal(groovifier);
        groovifierTraverser.process(ast);
	}

	/**
	 * @param tokenNames
	 * @param ast
	 */
	private static void modifyJavaASTintoGroovyAST(String[] tokenNames, AST ast) {
		Visitor java2groovyConverter = new Java2GroovyConverter(tokenNames);
        AntlrASTProcessor java2groovyTraverser = new PreOrderTraversal(java2groovyConverter);
        java2groovyTraverser.process(ast);
	}

	/**
	 * @param input
	 * @return
	 */
	private static JavaRecognizer getJavaParser(String input) {
		JavaRecognizer parser = null;
        SourceBuffer sourceBuffer = new SourceBuffer();
        UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input),sourceBuffer);
        JavaLexer lexer = new JavaLexer(unicodeReader);
        unicodeReader.setLexer(lexer);
        parser = JavaRecognizer.make(lexer);
        parser.setSourceBuffer(sourceBuffer);
		return parser;
	}

	public static String mindmap(String input) throws Exception{
        JavaRecognizer parser = getJavaParser(input);
        String[] tokenNames = parser.getTokenNames();
        parser.compilationUnit();
        AST ast = parser.getAST();
        // modify the Java AST into a Groovy AST
        modifyJavaASTintoGroovyAST(tokenNames, ast);
        String[] groovyTokenNames = getGroovyTokenNames(input);
        // groovify the fat Java-Like Groovy AST
        groovifyFatJavaLikeGroovyAST(ast, groovyTokenNames);

        // now output        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Visitor visitor = new MindMapPrinter(new PrintStream(baos),groovyTokenNames);
        AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);

        traverser.process(ast);
        
        return new String(baos.toByteArray());
    }

	public static String nodePrinter(String input) throws Exception{
        JavaRecognizer parser = getJavaParser(input);
        String[] tokenNames = parser.getTokenNames();
        parser.compilationUnit();
        AST ast = parser.getAST();
        // modify the Java AST into a Groovy AST
        modifyJavaASTintoGroovyAST(tokenNames, ast);
        String[] groovyTokenNames = getGroovyTokenNames(input);
        // groovify the fat Java-Like Groovy AST
        groovifyFatJavaLikeGroovyAST(ast, groovyTokenNames);

        // now output        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Visitor visitor = new NodePrinter(new PrintStream(baos),groovyTokenNames);
        AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);

        traverser.process(ast);
        
        return new String(baos.toByteArray());
    }

	private static String[] getGroovyTokenNames(String input) {
        GroovyRecognizer groovyParser = null;
        SourceBuffer groovySourceBuffer = new SourceBuffer();
        UnicodeEscapingReader groovyUnicodeReader = new UnicodeEscapingReader(new StringReader(input),groovySourceBuffer);
        GroovyLexer groovyLexer = new GroovyLexer(groovyUnicodeReader);
        groovyUnicodeReader.setLexer(groovyLexer);
        groovyParser = GroovyRecognizer.make(groovyLexer);
        return groovyParser.getTokenNames();
	}
	
}
