package com.googlecode.prolog_cafe.compiler;
import com.googlecode.prolog_cafe.lang.BufferingPrologControl;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.PrologException;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.LinkedList;
/**
 * The <code>Compiler</code> class provides methods for
 * translating Prolog programs into Java programs.
 *
 * The <code>Compiler</code> class supports the following compiler options.
 * All of them are set to <code>true</code> in default setting.
 * <ul>
 *   <li>Eliminate disjunctions
 *   <li>Arithmetic compilation
 *   <li>Inline expansion
 *   <li>Optimisation of recursive call
 *   <li>2nd. level indexing (<code>switch_on_hash</code>)
 * </ul>
 *
 * Let us show a sample session for translating a Prolog program
 * <code>$PLCAFEDIR/examples/prolog/list.pl</code> into Java.
 * The <code>list.pl</code> contains predicates
 * <code>append/3</code>, <code>nrev/2</code>, and <code>range/3</code>.
 * <ul>
 * <li>From Command line<br>
 * <pre>
 *    % java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.compiler.Compiler:$CLASSPATH $PLCAFEDIR/examples/prolog/list.pl
 *    Prolog Cafe X.X.X (YYY)
 *    Copyright(C) 1997-200X M.Banbara and N.Tamura
 *    % ls
 *    PRED_append_3.java      PRED_nrev_2.java        PRED_range_3.java
 * </pre>
 * <li>From Java program<br>
 * <pre>
 *    import com.googlecode.prolog_cafe.compiler.Compiler;
 *    public class T {
 *        public static void main(String argv[]) {
 *            Compiler comp = new Compiler();
 *	    comp.prologToJava(argv[0], ".");
 *        }
 *    }
 * </pre>
 * <pre>
 *    % javac -classpath $PLCAFEDIR/plcafe.jar:$CLASSPATH T.java
 *    % java -classpath $PLCAFEDIR/plcafe.jar:$CLASSPATH T $PLCAFEDIR/examples/prolog/list.pl
 *    % ls
 *    PRED_append_3.java      PRED_nrev_2.java        PRED_range_3.java
 * </pre>
 * </ul>
 *
 * It is noted that
 * our Prolog-to-Java translator is originally witten in Prolog, and then bootstrapped.
 * Please see the following two Prolog programs in details.
 * <ul>
 *   <li><code>$PLCAFEDIR/src/compiler/pl2am.pl</code><br>
 *       Translates a Prolog program into a WAM-based intermediate code.
 *   <li><code>$PLCAFEDIR/src/compiler/am2j.pl</code><br>
 *       Translates a WAM-based intermediate code generated by <code>pl2am.pl</code>
 *       into Java programs.
 * </ul>
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.2
 */
public class Compiler {
    public static enum Option {
      eliminateDisjunctions("ed", true),
      arithmeticCompilation("ac", true),
      inlineExpansion("ie", true),
      optimiseRecursiveCall("rc", true),
      switchOnHash("idx", true),
      generateClosure("clo", false);

      final SymbolTerm symbol;
      final boolean onByDefault;

      Option(String symbol, boolean onByDefault) {
        this.symbol = SymbolTerm.makeSymbol(symbol);
        this.onByDefault = onByDefault;
      }
    }

    /** Prolog context running the compiler/translater tools. */
    private BufferingPrologControl pcl;
    private EnumSet<Option> options;

    /** Initialize a new compiler instance. */
    public Compiler() {
      pcl = new BufferingPrologControl();
      options = EnumSet.noneOf(Option.class);
      enableDefaultOptions();
    }

    /**
     * Translates a Prolog program into a WAM-based intermediate code.
     *
     * @param _prolog an input Prolog file
     * @param _wam an output file for WAM-based intermediate code.
    */
    public void prologToWAM(String _prolog, String _wam) throws CompileException {
	    if (! fileExists(_prolog))
		  throw new CompileException(new FileNotFoundException(_prolog));

	    // Create arguments
	    Term prolog = SymbolTerm.makeSymbol(_prolog);
	    Term wam    = SymbolTerm.makeSymbol(_wam);
	    Term op     = Prolog.Nil;
	    for (Option opt : options)
	      op = new ListTerm(opt.symbol, op);

        ListTerm args = new ListTerm(prolog, new ListTerm(wam, new ListTerm(op, Prolog.Nil)));
	    try {
          if (!pcl.execute("com.googlecode.prolog_cafe.compiler.pl2am", "pl2am", args))
            throw new CompileException("Unknown Error");
	    } catch (PrologException err) {
	      throw new CompileException("Error compiling "+_prolog, err);
	    }
    }

    /**
     * Translates WAM-based intermediate code into Java source.
     *
     * @param _wam an input file for WAM-based intermediate code.
     * @param _dir a destination directory for java files.
     * @see #prologToWAM(String, String)
    */
    public void wamToJavaSource(String _wam, String _dir) throws CompileException {
	    if (! fileExists(_wam))
          throw new CompileException(new FileNotFoundException(_wam));
	   if (! fileExists(_dir) && !new File(_dir).mkdirs())
         throw new CompileException(new FileNotFoundException(_dir));

	    // Create arguments
	    Term wam    = SymbolTerm.makeSymbol(_wam);
	    Term dir    = SymbolTerm.makeSymbol(_dir);
	    ListTerm args = new ListTerm(wam, new ListTerm(dir, Prolog.Nil));
	    try {
	      if (!pcl.execute("com.googlecode.prolog_cafe.compiler.am2j", "am2j", args))
	        throw new CompileException("Unknown Error");
	    } catch (PrologException err) {
	       throw new CompileException("Error converting "+_wam, err);
	    }
    }

    /**
     * Translates a Prolog program into Java source files.
     *
     * @param prolog an input Prolog file
     * @param dir a destination directory for java files. The directory must already exist.
     * @see #prologToWAM(String, String)
     * @see #wamToJavaSource(String, String)
    */
    public void prologToJavaSource(String prolog, String dir) throws CompileException {
      File tmp;
      try {
        tmp = File.createTempFile("PrologCafe_", ".am");
      } catch (IOException e) {
        throw new CompileException("Cannot create temporary file", e);
      }
      try {
        prologToWAM(prolog, tmp.getPath());
        wamToJavaSource(tmp.getPath(), dir);
      } finally {
        if (!tmp.delete() && tmp.exists())
          tmp.deleteOnExit();
      }
    }

    public static void main(String argv[]) throws Exception {
      Compiler comp = new Compiler();
      String out = ".";
      String amdir = null;
      boolean stackTrace = false;
      LinkedList<String> plsrc = new LinkedList<String>();
      int argi = 0;
      for (; argi < argv.length; argi++) {
        String a = argv[argi];
        if (a.equals("--")) {
          argi++;
          break;
        }

        if (a.equals("-O")) {
          comp.enableDefaultOptions();

        } else if (a.equals("-O:none")) {
          comp.options.clear();

        } else if (a.startsWith("-O:")) {
          String optname = a.substring("-O:".length());
          Option opt = findOptionByName(optname);
          if (opt != null)
            comp.enable(opt);

        } else if (a.equals("-s")) {
          if (++argi == argv.length)
            usage();
          out = argv[argi];

        } else if (a.equals("-am")) {
          if (++argi == argv.length)
            usage();
          amdir = argv[argi];

        } else if (a.equals("-h") || a.equals("--help") || a.equals("-help")) {
          usage();

        } else if (a.equals("--show-stack-trace")) {
          stackTrace = true;

        } else if (a.startsWith("-")) {
          System.err.println("error: Unsupported flag '" + a + "'");
          usage();

        } else {
          plsrc.add(a);
        }
      }
      if (argi < argv.length)
        plsrc.addAll(Arrays.asList(argv).subList(argi, argv.length));
      if (plsrc.isEmpty())
        usage();

      banner();
      for (String pl : plsrc) {
        System.err.println("Translating " + pl);

        try {
          if (amdir != null) {
            String base;
            if (pl.endsWith(".pl"))
              base = pl.substring(0, pl.length() - 3);
            else
              base = pl;
            File am = new File(new File(amdir), base + ".am");
            am.getParentFile().mkdirs();

            comp.prologToWAM(pl, am.getPath());
            comp.wamToJavaSource(am.getPath(), out);
          } else {
            comp.prologToJavaSource(pl, out);
          }
        } catch (CompileException err) {
          if (stackTrace)
            err.printStackTrace();
          else
            System.err.println("error: " + err.getMessage());
          System.exit(1);
        }
      }
    }

    private static Option findOptionByName(String optname) {
      for (Option opt : Option.values()) {
        if (opt.toString().equalsIgnoreCase(optname))
          return opt;
        if (opt.symbol.name().equalsIgnoreCase(optname))
          return opt;
      }
      System.err.println("error: Unsupported option '" + optname + "'");
      System.exit(1);
      throw new RuntimeException("System.exit(1)");
    }

    private static void usage() {
      System.err.print("usage: ");
      System.err.print("java ");
      System.err.print(Compiler.class.getName());
      System.err.print(" [options]");
      System.err.print(" prolog_source...");
      System.err.println();
      banner();

      String optfmt = "  %-20s %s";
      System.err.format(optfmt, "-s <directory>", "where to place generated source files");
      System.err.println();
      System.err.format(optfmt, "-am <directory>", "save WAM intermediate files");
      System.err.println();

      System.err.format(optfmt, "-O", "enable all optimizations");
      System.err.println();
      System.err.format(optfmt, "-O:none", "disable all optimizations");
      System.err.println();

      // Special options not related to building Prolog programs.
      System.err.println();
      System.err.format(optfmt, "-h, --help", "display this message");
      System.err.println();
      System.err.format(optfmt, "--show-stack-trace", "show Java stack trace on failure");
      System.err.println();

      System.exit(1);
    }

    private static void banner() {
      System.err.println("Prolog Cafe");
      System.err.println("Copyright(C) 1997-2009 M.Banbara and N.Tamura");
      System.err.println();
    }

    private static boolean fileExists(String _file) {
	try {
	    return new File(_file).exists();
	} catch (SecurityException e) {}
	return false;
    }

    public boolean isEnabled(Option opt) { return options.contains(opt); }
    public void enable(Option opt) { options.add(opt); }
    public void disable(Option opt) { options.remove(opt); }
    public void setEnabled(Option opt, boolean on) {
      if (on)
        enable(opt);
      else
        disable(opt);
    }

    private void enableDefaultOptions() {
      for (Option opt : Option.values())
        if (opt.onByDefault)
          options.add(opt);
    }
}
