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.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");

    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.intern("$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; }
}
