package com.googlecode.prolog_cafe.lang;

import java.util.Set;

/**
 * Tracks current evaluation goal and results.
 * <p>
 * On success/1 or fail/1 the corresponding methods in this class are invoked,
 * allowing the implementation to message the results to the application. During
 * any reduction loops the {@link #isEngineStopped()} method is consulted to
 * determine if the loop should terminate.
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.2
 */
public abstract class PrologControl {
    /** Holds a Prolog engine. */
    protected Prolog engine;

    /** Holds a Prolog goal to be executed. */
    protected Operation code;

    /** Constructs a new <code>PrologControl</code>. */
    public PrologControl() {
	engine = new Prolog(this);
	code = null;
    }

    public boolean isEnabled(Prolog.Feature f) {
      return engine.features.contains(f);
    }

    public void setEnabled(Prolog.Feature f, boolean on) {
      if (on)
        engine.features.add(f);
      else
        engine.features.remove(f);
    }

    public void setEnabled(Set<Prolog.Feature> f, boolean on) {
      if (on)
        engine.features.addAll(f);
      else
        engine.features.removeAll(f);
    }

    public int getMaxDatabaseSize() {
      if (engine.internalDB != null)
        return engine.internalDB.maxContents;
      return InternalDatabase.DEFAULT_SIZE;
    }
    public void setMaxDatabaseSize(int size) {
      if (engine.aregs != null)
        throw new IllegalStateException("Prolog already initialized");
      engine.internalDB = new InternalDatabase(size);
    }

    public PrologClassLoader getPrologClassLoader() {
      if (engine.pcl == null)
        engine.pcl = new PrologClassLoader();
      return engine.pcl;
    }
    public void setPrologClassLoader(PrologClassLoader cl) {
      if (engine.aregs != null)
        throw new IllegalStateException("Prolog already initialized");
      engine.pcl = cl;
    }

    public int getMaxArity() { return engine.getMaxArity(); }
    public void setMaxArity(int max) {
      if (max < 8)
        throw new IllegalStateException("invalid arity " + max);
      if (engine.aregs != null)
        throw new IllegalStateException("Prolog already initialized");
      engine.maxArity = max;
    }

    /** Sets a goal and its arguments to this Prolog thread. 
     * An initial continuation goal (a <code>Success</code> object)
     * is set to the <code>cont</code> field of goal <code>p</code> as continuation.
     */
    public void setPredicate(Predicate p) {
      p.cont = Success.SUCCESS;
      code = p;
    }

    /** Sets a goal <code>call(t)</code> to this Prolog thread. 
     * An initial continuation goal (a <code>Success</code> object)
     * is set to the <code>cont</code> field of goal <code>p</code> as continuation.
     */
    public void setPredicate(String pkg, String functor, Term... args) {
      setPredicate(getPrologClassLoader().predicate(pkg, functor, args));
    }

    /** Sets a goal <code>call(t)</code> to this Prolog thread.
     * An initial continuation goal (a <code>Success</code> object)
     * is set to the <code>cont</code> field of <code>call(t)</code> as continuation.
     */
    public void setPredicate(Term t)  {
      setPredicate(Prolog.BUILTIN, "call", t);
    }

    /**
     * Is invoked when the system succeeds to find a solution.<br>
     *
     * This method is invoked from the initial continuation goal
     * (a <code>Success</code> object).
     */
    protected abstract void success();

    /** Is invoked after failure of all trials. */
    protected abstract void fail();

    /**
     * Check if evaluation should continue.
     * <p>
     * This method gets invoked on every predicate reduction. If the control class
     * wants to halt execution (for example sufficient results were obtained, or a
     * limit on running time or reduction count has been reached) the method must
     * return true to stop execution.
     *
     * @return true if the engine is no longer supposed to execute; false if
     *         another predicate reduction can take place.
     */
    public abstract boolean isEngineStopped();

    /**
     * Execute the predicate on the current thread.
     * <p>
     * This method does not return until {@link #isEngineStopped()} returns true.
     * Implementors of the class are expected to invoke this method to perform
     * evaluation, and terminate out of the loop at the proper time based on an
     * invocation to {@link #success()} or {@link #fail()}.
     *
     * @throws PrologException
     * @throws JavaInterruptedException
     */
    protected void executePredicate()
      throws PrologException, JavaInterruptedException {
	    engine.init();
	    main_loop:while(true) {
		while (engine.exceptionRaised == 0) {
		    if (isEngineStopped())
			break main_loop;
		    code = code.exec(engine);
		}
		switch (engine.exceptionRaised) {
		case 1:  // halt/0
		    break main_loop;
		case 2:  // freeze/2
		    throw new SystemException("freeze/2 is not supported yet");
		    // Do something here
		    // engine.exceptionRaised = 0 ;
		    // break;
		default:
		    throw new SystemException("Invalid value of exceptionRaised");
		}
	    }
    }

    /** @param err stack trace to print (or log). */
    public void printStackTrace(Throwable err) {
      err.printStackTrace();
    }
}
