package com.googlecode.prolog_cafe.lang;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.PushbackReader;
import java.io.Reader;
import java.io.Writer;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
/**
 * Prolog engine.
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.2
*/
public final class Prolog {
    private static final SymbolTerm NONE = SymbolTerm.intern("$none");

    /** Prolog thread */
    public PrologControl control;

    /** Argument registers */
    public Term areg1, areg2, areg3, areg4, areg5, areg6, areg7, areg8;
    public Term[] aregs;
    private static final Term[] NO_REGISTERS = {};

    /** Continuation goal register */
    public Operation cont;
    /** Choice point frame stack */
    public final ChoicePointStack stack;
    /** Trail stack */
    public final Trail trail;
    /** Cut pointer */
    public int B0;
    /** Class loader */
    public PrologClassLoader pcl;
    /** Internal Database */
    public InternalDatabase internalDB;

    /** Current time stamp of choice point frame */
    protected long CPFTimeStamp;

    /**
     * Exception level of continuation passing loop:
     * <li><code>0</code> for no exception,
     * <li><code>1</code> for <code>halt/0</code>,
     * <li><code>1+N</code> for <code>halt(N)</code>.
     * </ul>
     */
    public int halt;

    /** <font color="red">Not supported yet</font>. Prolog implementation flag: <code>bounded</code>. */
    protected boolean bounded = false;
    /** Prolog implementation flag: <code>max_integer</code>. */
    protected static final int maxInteger = Integer.MAX_VALUE;
    /** Prolog implementation flag: <code>min_integer</code>. */
    protected static final int minInteger = Integer.MIN_VALUE;
    /** Prolog implementation flag: <code>integer_rounding_function</code>. */
    protected String integerRoundingFunction = "down";
    /** <font color="red">Not supported yet</font>. Prolog implementation flag: <code>char_conversion</code>. */
    protected String charConversion;
    /** Prolog implementation flag: <code>debug</code>. */
    protected String debug;
    /** Prolog implementation flag: <code>max_arity</code>. */
    protected int maxArity = 255;
    /** Prolog implementation flag: <code>unknown</code>. */
    protected String unknown;
    /** <font color="red">Not supported yet</font>. Prolog implementation flag: <code>double_quotes</code>. */
    protected String doubleQuotes;
    /** Prolog implementation flag: <code>print_stack_trace</code>. */
    protected String printStackTrace;

    /** Holds an exception term for <code>catch/3</code> and <code>throw/1</code>. */
    protected Term exception;

    /** Holds the start time as <code>long</code> for <code>statistics/2</code>. */
    protected long startRuntime;
    /** Holds the previous time as <code>long</code> for <code>statistics/2</code>. */
    protected long previousRuntime;

    /** Hashtable for creating a copy of term. */
    protected final IdentityHashMap<VariableTerm,VariableTerm> copyHash;

    /** The size of the pushback buffer used for creating input streams. */
    public static final int PUSHBACK_SIZE = 3;

    /** Standard input stream. */
    protected transient PushbackReader userInput;
    /** Standard output stream. */
    protected transient PrintWriter userOutput;
    /** Standard error stream. */
    protected transient PrintWriter userError;
    /** Current input stream. */
    protected transient PushbackReader currentInput;
    /** Current output stream. */
    protected transient PrintWriter currentOutput;
    /** Hashtable for managing input and output streams. */
    protected HashtableOfTerm streamManager;

    /** Hashtable for managing internal databases. */
    protected final HashtableOfTerm hashManager;

    /** Name of the builtin package. */
    public static final String BUILTIN = "com.googlecode.prolog_cafe.builtin";

    /** Holds an atom <code>[]<code> (empty list). */
    public static final SymbolTerm Nil     = SymbolTerm.intern("[]");

    /* Some symbols for stream options */
    static final SymbolTerm SYM_MODE_1     = SymbolTerm.intern("mode", 1);
    static final SymbolTerm SYM_ALIAS_1    = SymbolTerm.intern("alias", 1);
    static final SymbolTerm SYM_TYPE_1     = SymbolTerm.intern("type", 1);
    static final SymbolTerm SYM_READ       = SymbolTerm.intern("read");
    static final SymbolTerm SYM_APPEND     = SymbolTerm.intern("append");
    static final SymbolTerm SYM_INPUT      = SymbolTerm.intern("input");
    static final SymbolTerm SYM_OUTPUT     = SymbolTerm.intern("output");
    static final SymbolTerm SYM_TEXT       = SymbolTerm.intern("text");
    static final SymbolTerm SYM_USERINPUT  = SymbolTerm.intern("user_input");
    static final SymbolTerm SYM_USEROUTPUT = SymbolTerm.intern("user_output");
    static final SymbolTerm SYM_USERERROR  = SymbolTerm.intern("user_error");

    private static final PrintWriter NO_OUTPUT = new PrintWriter(new Writer() {
      @Override
      public void write(char[] cbuf, int off, int len) throws IOException {
        throw new IOException("Prolog.Feature.IO disabled");
      }

      @Override
      public void flush() throws IOException {
      }

      @Override
      public void close() throws IOException {
      }
    });

    private static final PushbackReader NO_INPUT = new PushbackReader(new Reader() {
      @Override
      public int read(char[] cbuf, int off, int len) throws IOException {
        return -1;
      }

      @Override
      public void close() throws IOException {
      }
    });

    public static enum Feature {
      /** Access to the local filesystem and console. */
      IO,

      /** Track the running time of evaluations */
      STATISTICS_RUNTIME;
    }
    protected final EnumSet<Feature> features = EnumSet.allOf(Feature.class);

    Prolog(PrologControl c) {
      control = c;
      trail = new Trail();
      stack = new ChoicePointStack(trail);
      copyHash = new IdentityHashMap<VariableTerm, VariableTerm>();
      hashManager = new HashtableOfTerm();
    }

    Prolog(PrologControl c, PrologMachineCopy pmc) {
      control = c;
      trail = new Trail();
      stack = new ChoicePointStack(trail);
      copyHash = new IdentityHashMap<VariableTerm, VariableTerm>();
      pcl = pmc.pcl;

      // During restore there is no need to copy terms. clause/2 inside of
      // builtins.pl copies the predicate when it reads from internalDB.
      hashManager = PrologMachineCopy.copyShallow(pmc.hashManager);
      internalDB = new InternalDatabase(this, pmc.internalDB, false);
    }

    /**
     * Initializes some local instances only once.
     * This <code>initOnce</code> method is invoked in the constructor
     * and initializes the following instances:
     * <ul>
     *   <li><code>userInput</code>
     *   <li><code>userOutput</code>
     *   <li><code>userError</code>
     *   <li><code>copyHash</code>
     *   <li><code>streamManager</code>
     * </ul>
     */
  private void initOnce() {
    if (8 < maxArity)
      aregs = new Term[maxArity - 8];
    else
      aregs = NO_REGISTERS;

    if (pcl == null) pcl = new PrologClassLoader();
    if (internalDB == null) internalDB = new InternalDatabase();

    streamManager = new HashtableOfTerm();

    if (features.contains(Feature.IO)) {
      userInput = new PushbackReader(new BufferedReader(new InputStreamReader(System.in)), PUSHBACK_SIZE);
      userOutput = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), true);
      userError = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err)), true);

      streamManager.put(SYM_USERINPUT, new JavaObjectTerm(userInput));
      streamManager.put(new JavaObjectTerm(userInput),
        makeStreamProperty(SYM_READ, SYM_INPUT, SYM_USERINPUT, SYM_TEXT));

      streamManager.put(SYM_USEROUTPUT, new JavaObjectTerm(userOutput));
      streamManager.put(new JavaObjectTerm(userOutput),
        makeStreamProperty(SYM_APPEND, SYM_OUTPUT, SYM_USEROUTPUT, SYM_TEXT));

      streamManager.put(SYM_USERERROR, new JavaObjectTerm(userError));
      streamManager.put(new JavaObjectTerm(userError),
        makeStreamProperty(SYM_APPEND, SYM_OUTPUT, SYM_USERERROR, SYM_TEXT));
    } else {
      userInput = NO_INPUT;
      userOutput = NO_OUTPUT;
      userError = userOutput;
    }
  }

    /** Initializes this Prolog engine. */
    public void init() { 
	if (aregs == null)
	  initOnce();
	stack.init();
	trail.init();
	B0 = stack.top();
	CPFTimeStamp = Long.MIN_VALUE;

	// Creates an initial choice point frame.
	ChoicePointFrame initialFrame = ChoicePointFrame.S0(null);
	initialFrame.b0 = B0;
	initialFrame.bp = Failure.FAILURE;
	initialFrame.tr = trail.top();
	initialFrame.timeStamp = ++CPFTimeStamp;
	stack.push(initialFrame);

	halt = 0;

	charConversion  = "off";
	debug           = "off";
	unknown         = "error";
	doubleQuotes    = "codes";
	printStackTrace = "off";

	exception = NONE;
	startRuntime = features.contains(Feature.STATISTICS_RUNTIME)
	    ? System.currentTimeMillis()
	    : 0;
	previousRuntime = 0;

	currentInput  = userInput;
	currentOutput = userOutput;
    }

    /** Ensure a feature is enabled, throwing if not. */
    public void requireFeature(Prolog.Feature f, Operation goal, Term arg) {
      if (!features.contains(f)) {
        throw new PermissionException(goal, "use", f.toString().toLowerCase(), arg, "disabled");
      }
    }

    /** Sets B0 to the top of the choice point stack.. */
    public void setB0()    { B0 = stack.top(); }

    /** Discards all choice points after the value of <code>i</code>. */
    public void cut(int i) { stack.cut(i); }

    /** Discards all choice points after the value of <code>B0</code>. */
    public void neckCut()  { stack.cut(B0); }

    /**
     * Returns a copy of term <code>t</code>. 
     * @param t a term to be copied. It must be dereferenced.
     */
    public Term copy(Term t) {
	copyHash.clear();
	return t.copy(this);
    }

    /** 
     * Do backtrak.
     * This method restores the value of <code>B0</code>
     * and returns the backtrak point in current choice point.
     */
    public Operation fail() {
	ChoicePointFrame top = stack.top;
	B0 = top.b0;     // restore B0
	return top.bp;   // execute next clause
    }

    /** 
     * Returns the <code>Predicate</code> object refered, respectively, 
     * <code>var</code>, <code>Int</code>, <code>flo</code>, 
     * <code>con</code>, <code>str</code>, or <code>lis</code>, 
     * depending on whether the dereferenced value of argument 
     * register <code>areg[1]</code> is a
     * variable, integer, float,
     * atom, compound term, or non-empty list, respectively.
     */
    public Operation switch_on_term(Operation var, 
				    Operation Int, 
				    Operation flo,
				    Operation con, 
				    Operation str, 
				    Operation lis) {
	Term arg1 = areg1.dereference();
	if (arg1.isVariable())
	    return var;
	if (arg1.isInteger())
	    return Int;
	if (arg1.isDouble())
	    return flo;
	if (arg1.isSymbol())
	    return con;
	if (arg1.isStructure())
	    return str;
	if (arg1.isList())
	    return lis;
	return var;
    }

    /**
     * If the dereferenced value of arugment register <code>areg[1]</code>
     * is an integer, float, atom, or compound term (except for non-empty list),
     * this returns the <code>Predicate</code> object to which its key is mapped
     * in hashtable <code>hash</code>.
     *
     * The key is calculated as follows:
     * <ul>
     *   <li>integer - itself
     *   <li>float - itself
     *   <li>atom - itself
     *   <li>compound term - functor/arity
     * </ul>
     *
     * If there is no mapping for the key of <code>areg[1]</code>, 
     * this returns <code>otherwise</code>.
     */
    public Operation switch_on_hash(HashMap<Term,Operation> hash, Operation otherwise) {
	Term arg1 = areg1.dereference();
	Term key;
	if (arg1.isInteger() || arg1.isDouble() || arg1.isSymbol()) {
	    key = arg1;
	} else if (arg1.isStructure()) {
	    key = ((StructureTerm) arg1).functor();
	} else {
	    throw new SystemException("Invalid argument in switch_on_hash");
	}
	Operation p = hash.get(key);
	if (p != null)
	    return p;
	else 
	    return otherwise;
    }

    /** Restores the argument registers and continuation goal register from the current choice point frame. */
    public void restore() {
      stack.top.restore(this);
    }

    /** Creates a new choice point frame. */
    public Operation jtry0(Operation p, Operation next) { return finishjtry(p, next, ChoicePointFrame.S0(cont)); }
    public Operation jtry1(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S1(this)); }
    public Operation jtry2(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S2(this)); }
    public Operation jtry3(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S3(this)); }
    public Operation jtry4(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S4(this)); }
    public Operation jtry5(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S5(this)); }
    public Operation jtry6(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S6(this)); }
    public Operation jtry7(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S7(this)); }
    public Operation jtry8(Operation p, Operation next) { return finishjtry(p, next, new ChoicePointFrame.S8(this)); }
    public Operation jtry(int arity, Operation p, Operation next) {
	return finishjtry(p, next, new ChoicePointFrame.S9(arity, this));
    }

    private Operation finishjtry(Operation p, Operation next, ChoicePointFrame entry) {
      entry.b0 = B0;
      entry.bp = next;
      entry.tr = trail.top();
      entry.timeStamp = ++CPFTimeStamp;
      stack.push(entry);
      return p;
    }

    /** 
     * Resets all necessary information from the current choice point frame,
     * updates its next clause field to <code>next</code>,
     * and then returns <code>p</code>.
     */
    public Operation retry(Operation p, Operation next) {
	restore();
	ChoicePointFrame top = stack.top;
	trail.unwind(top.tr);
	top.bp = next;
	return p;
    }

    /** 
     * Resets all necessary information from the current choice point frame,
     * discard it, and then returns <code>p</code>.
     */
    public Operation trust(Operation p) {
	restore();
	trail.unwind(stack.top.tr);
	stack.delete();
	return p;
    }

    Term makeStreamProperty(SymbolTerm _mode, SymbolTerm io, SymbolTerm _alias, SymbolTerm _type) {
	Term[] mode  = {_mode};
	Term[] alias = {_alias};
	Term[] type  = {_type};

	Term t = Nil;
	t = new ListTerm(new StructureTerm(SYM_MODE_1,  mode ), t);
	t = new ListTerm(io, t);
	t = new ListTerm(new StructureTerm(SYM_ALIAS_1, alias), t);
	t = new ListTerm(new StructureTerm(SYM_TYPE_1,  type ), t);
	return t;
    }

    /** Returns the current time stamp of choice point frame. */
    public long    getCPFTimeStamp() { return CPFTimeStamp; }

    /** Returns the value of Prolog implementation flag: <code>bounded</code>. */
    public boolean isBounded() { return bounded; }

    /** Returns the value of Prolog implementation flag: <code>max_integer</code>. */
    public int getMaxInteger() { return maxInteger; }

    /** Returns the value of Prolog implementation flag: <code>min_integer</code>. */
    public int getMinInteger() { return minInteger; }

    /** Returns the value of Prolog implementation flag: <code>integer_rounding_function</code>. */
    public String getIntegerRoundingFunction() { return integerRoundingFunction; }

    /** Returns the value of Prolog implementation flag: <code>char_conversion</code>. */
    public String getCharConversion() { return charConversion; }
    /** Sets the value of Prolog implementation flag: <code>char_conversion</code>. */
    public void setCharConversion(String mode) { charConversion = mode;}

    /** Returns the value of Prolog implementation flag: <code>debug</code>. */
    public String getDebug() { return debug; }
    /** Sets the value of Prolog implementation flag: <code>debug</code>. */
    public void setDebug(String mode) { debug = mode;}

    /** Returns the value of Prolog implementation flag: <code>max_arity</code>. */
    public int getMaxArity() { return maxArity; }

    /** Returns the value of Prolog implementation flag: <code>unknown</code>. */
    public String getUnknown() { return unknown; }
    /** Sets the value of Prolog implementation flag: <code>unknown</code>. */
    public void setUnknown(String mode) { unknown = mode;}

    /** Returns the value of Prolog implementation flag: <code>double_quotes</code>. */
    public String getDoubleQuotes() { return doubleQuotes; }
    /** Sets the value of Prolog implementation flag: <code>double_quotes</code>. */
    public void setDoubleQuotes(String mode) { doubleQuotes = mode;}

    /** Returns the value of Prolog implementation flag: <code>print_stack_trace</code>. */
    public String getPrintStackTrace() { return printStackTrace; }
    /** Sets the value of Prolog implementation flag: <code>print_stack_trace</code>. */
    public void setPrintStackTrace(String mode) { printStackTrace = mode;}

    /** Returns the value of <code>exception</code>. This is used in <code>catch/3</code>. */
    public Term getException() { return exception; }
    /** Sets the value of <code>exception</code>. This is used in <code>throw/1</code>. */
    public void setException(Term t) { exception = t;}

    /** Returns the value of <code>startRuntime</code>. This is used in <code>statistics/2</code>. */
    public long getStartRuntime() { return startRuntime; }

    /** Returns the value of <code>previousRuntime</code>. This is used in <code>statistics/2</code>. */
    public long getPreviousRuntime() { return previousRuntime; }
    /** Sets the value of <code>previousRuntime</code>. This is used in <code>statistics/2</code>. */
    public void setPreviousRuntime(long t) { previousRuntime = t; }

    /** Returns the standard input stream. */
    public PushbackReader  getUserInput() { return userInput; }
    /** Returns the standard output stream. */
    public PrintWriter     getUserOutput() { return userOutput; }
    /** Returns the standard error stream. */
    public PrintWriter     getUserError() { return userError; }

    /** Returns the current input stream. */
    public PushbackReader  getCurrentInput() { return currentInput; }
    /** Sets the current input stream to <code>in</code>. */
    public void            setCurrentInput(PushbackReader in) { currentInput = in; }

    /** Returns the current output stream. */
    public PrintWriter     getCurrentOutput() { return currentOutput; }
    /** Sets the current output stream to <code>out</code>. */
    public void            setCurrentOutput(PrintWriter out) { currentOutput = out; }

    /** Returns the stream manager. */
    public HashtableOfTerm getStreamManager() { return streamManager; }

    /** Returns the hash manager. */
    public HashtableOfTerm getHashManager() { return hashManager; }
}
