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;
/**
 * 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 {
    /** Prolog thread */
    public PrologControl control;
    /** Argument registers */
    public Term areg1, areg2, areg3, areg4, areg5, areg6, areg7, areg8;
    public Term[] aregs;
    /** 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>2</code> for <code>freeze/2</code> (not supported yet)
     * </ul>
     */
    public int exceptionRaised;

    /** <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 HashMap<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.makeSymbol("[]");

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

    public static enum Feature {
      /** Enable the {@code java_*} predicates, supporting reflection in Prolog. */
      JAVA_REFLECTION,

      /** Access to the local filesystem and console. */
      IO;
    }
    protected final EnumSet<Feature> features = EnumSet.allOf(Feature.class);

    /** Constructs new Prolog engine. */
    public Prolog(PrologControl c) { 
	control    = c;
	cont       = null;
	trail      = new Trail();
	stack      = new ChoicePointStack(trail);
	hashManager = new HashtableOfTerm();
    }

    /**
     * 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>
     */
  protected void initOnce() {
    aregs = new Term[Math.max(0, maxArity - 8)];
    if (pcl == null) pcl = new PrologClassLoader();
    if (internalDB == null) internalDB = new InternalDatabase();

    copyHash = new HashMap<VariableTerm, VariableTerm>();
    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 = new PushbackReader(new Reader() {
        @Override
        public int read(char[] cbuf, int off, int len) throws IOException {
          return -1;
        }

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

      userOutput = 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 {
        }
      });
      userError = userOutput;
    }
  }

    /** Initializes this Prolog engine. */
    public void init() { 
	if (aregs == null)
	  initOnce();
	stack.init();
	trail.init();
	//	pdl.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);

	exceptionRaised = 0;

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

	exception       = SymbolTerm.makeSymbol("$none");
	startRuntime    = System.currentTimeMillis();
	previousRuntime = 0;

	userOutput.flush();
	userError.flush();
	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; }
}
