package com.googlecode.prolog_cafe.compiler;
import com.googlecode.prolog_cafe.exceptions.CompileException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
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.PrologClassLoader;
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.intern(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();
      pcl.setEnabled(EnumSet.allOf(Prolog.Feature.class), true);
      pcl.setPrologClassLoader(new PrologClassLoader(Compiler.class.getClassLoader()));
      pcl.setReductionLimit(Long.MAX_VALUE);
      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.create(_prolog);
	    Term wam    = SymbolTerm.create(_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.create(_wam);
	    Term dir    = SymbolTerm.create(_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<>();
      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);
    }
}
