/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package sample.preproc;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Vector;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.ClassPool;

/**
 * This is a preprocessor for Java source programs using annotated
 * import declarations.
 *
 * <ul><pre>
 * import <i>class-name</i> by <i>assistant-name</i> [(<i>arg1, arg2, ...</i>)]
 * </pre></ul>
 *
 * <p>To process this annotation, run this class as follows:
 *
 * <ul><pre>
 * java sample.preproc.Compiler sample.j
 * </pre></ul>
 *
 * <p>This command produces <code>sample.java</code>, which only includes
 * regular import declarations.  Also, the Javassist program
 * specified by <i>assistant-name</i> is executed so that it produces
 * class files under the <code>./tmpjvst</code> directory.  The class
 * specified by <i>assistant-name</i> must implement
 * <code>sample.preproc.Assistant</code>.
 *
 * @see sample.preproc.Assistant
 */

public class Compiler {
    protected BufferedReader input;
    protected BufferedWriter output;
    protected ClassPool classPool;

    /**
     * Constructs a <code>Compiler</code> with a source file.
     *
     * @param inputname         the name of the source file.
     */
    public Compiler(String inputname) throws CannotCompileException {
        try {
            input = new BufferedReader(new FileReader(inputname));
        }
        catch (IOException e) {
            throw new CannotCompileException("cannot open: " + inputname);
        }

        String outputname = getOutputFilename(inputname);
        if (outputname.equals(inputname))
            throw new CannotCompileException("invalid source name: "
                                             + inputname);

        try {
            output = new BufferedWriter(new FileWriter(outputname));
        }
        catch (IOException e) {
            throw new CannotCompileException("cannot open: " + outputname);
        }

        classPool = ClassPool.getDefault();
    }

    /**
     * Starts preprocessing.
     */
    public void process() throws IOException, CannotCompileException {
        int c;
        CommentSkipper reader = new CommentSkipper(input, output);
        while ((c = reader.read()) != -1) {
            output.write(c);
            if (c == 'p') {
                if (skipPackage(reader))
                    break;
            }
            else if (c == 'i')
                readImport(reader);
            else if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
                break;
        }

        while ((c = input.read()) != -1)
            output.write(c);

        input.close();
        output.close();
    }

    private boolean skipPackage(CommentSkipper reader) throws IOException {
        int c;
        c = reader.read();
        output.write(c);
        if (c != 'a')
            return true;

        while ((c = reader.read()) != -1) {
            output.write(c);
            if (c == ';')
                break;
        }

        return false;
    }

    private void readImport(CommentSkipper reader)
                                throws IOException, CannotCompileException
    {
        int word[] = new int[5];
        int c;
        for (int i = 0; i < 5; ++i) {
            word[i] = reader.read();
            output.write(word[i]);
        }

        if (word[0] != 'm' || word[1] != 'p' || word[2] != 'o'
            || word[3] != 'r' || word[4] != 't')
            return;     // syntax error?

        c = skipSpaces(reader, ' ');
        StringBuffer classbuf = new StringBuffer();
        while (c != ' ' && c != '\t' && c != '\n' && c != '\r'
               && c != ';' && c != -1) {
            classbuf.append((char)c);
            c = reader.read();
        }

        String importclass = classbuf.toString();
        c = skipSpaces(reader, c);
        if (c == ';') {
            output.write(importclass);
            output.write(';');
            return;
        }
        if (c != 'b')
            syntaxError(importclass);

        reader.read();  // skip 'y'

        StringBuffer assistant = new StringBuffer();
        Vector args = new Vector();
        c = readAssistant(reader, importclass, assistant, args);
        c = skipSpaces(reader, c);
        if (c != ';')
            syntaxError(importclass);

        runAssistant(importclass, assistant.toString(), args);
    }

    void syntaxError(String importclass) throws CannotCompileException {
        throw new CannotCompileException("Syntax error.  Cannot import "
                                         + importclass);
    }

    int readAssistant(CommentSkipper reader, String importclass,
                      StringBuffer assistant, Vector args)
        throws IOException, CannotCompileException
    {
        int c = readArgument(reader, assistant);
        c = skipSpaces(reader, c);
        if (c == '(') {
            do {
                StringBuffer arg = new StringBuffer();
                c = readArgument(reader, arg);
                args.addElement(arg.toString());
                c = skipSpaces(reader, c);
            } while (c == ',');

            if (c != ')')
                syntaxError(importclass);

            return reader.read();
        }

        return c;
    }

    int readArgument(CommentSkipper reader, StringBuffer buf)
        throws IOException
    {
        int c = skipSpaces(reader, ' ');
        while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
               || '0' <= c && c <= '9' || c == '.' || c == '_') {
            buf.append((char)c);
            c = reader.read();
        }

        return c;
    }

    int skipSpaces(CommentSkipper reader, int c) throws IOException {
        while (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
            if (c == '\n' || c == '\r')
                output.write(c);

            c = reader.read();
        }

        return c;
    }

    /**
     * Is invoked if this compiler encoutenrs:
     *
     * <ul><pre>
     * import <i>class name</i> by <i>assistant</i> (<i>args1</i>, <i>args2</i>, ...);
     * </pre></ul>
     *
     * @param   classname       class name
     * @param   assistantname   assistant
     * @param   argv            args1, args2, ...
     */
    private void runAssistant(String importname, String assistantname,
                              Vector argv)
        throws IOException, CannotCompileException
    {
        Class assistant;
        Assistant a;
        int s = argv.size();
        String[] args = new String[s];
        for (int i = 0; i < s; ++i)
            args[i] = (String)argv.elementAt(i);

        try {
            assistant = Class.forName(assistantname);
        }
        catch (ClassNotFoundException e) {
            throw new CannotCompileException("Cannot find " + assistantname);
        }

        try {
            a = (Assistant)assistant.newInstance();
        }
        catch (Exception e) {
            throw new CannotCompileException(e);
        }

        CtClass[] imports = a.assist(classPool, importname, args);
        s = imports.length;
        if (s < 1)
            output.write(" java.lang.Object;");
        else {
            output.write(' ');
            output.write(imports[0].getName());
            output.write(';');
            for (int i = 1; i < s; ++i) {
                output.write(" import ");
                output.write(imports[1].getName());
                output.write(';');
            }
        }
    }

    private String getOutputFilename(String input) {
        int i = input.lastIndexOf('.');
        if (i < 0)
            i = input.length();

        return input.substring(0, i) + ".java";
    }

    public static void main(String[] args) {
        if (args.length > 0)
            try {
                Compiler c = new Compiler(args[0]);
                c.process();
            }
            catch (IOException e) {
                System.err.println(e);
            }
            catch (CannotCompileException e) {
                System.err.println(e);
            }
        else {
            System.err.println("Javassist version " + CtClass.version);
            System.err.println("No source file is specified.");
        }
    }
}

class CommentSkipper {
    private BufferedReader input;
    private BufferedWriter output;

    public CommentSkipper(BufferedReader reader, BufferedWriter writer) {
        input = reader;
        output = writer;
    }

    public int read() throws IOException {
        int c;
        while ((c = input.read()) != -1)
            if (c != '/')
                return c;
            else {
                c = input.read();
                if (c == '/')
                    skipCxxComments();
                else if (c == '*')
                    skipCComments();
                else 
                    output.write('/');
            }

        return c;
    }

    private void skipCxxComments() throws IOException {
        int c;
        output.write("//");
        while ((c = input.read()) != -1) {
            output.write(c);
            if (c == '\n' || c == '\r')
                break;
        }
    }

    private void skipCComments() throws IOException {
        int c;
        boolean star = false;
        output.write("/*");
        while ((c = input.read()) != -1) {
            output.write(c);
            if (c == '*')
                star = true;
            else if(star && c == '/')
                break;
            else
                star = false;
        }
    }
}
