package com.googlecode.prolog_cafe.builtin;
import com.googlecode.prolog_cafe.exceptions.ExistenceException;
import com.googlecode.prolog_cafe.exceptions.IllegalDomainException;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
import com.googlecode.prolog_cafe.exceptions.SystemException;
import com.googlecode.prolog_cafe.exceptions.TermException;
import com.googlecode.prolog_cafe.lang.HashtableOfTerm;
import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import com.googlecode.prolog_cafe.lang.VariableTerm;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.PushbackReader;
/**
 * <code>close/2</code><br>
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.0
*/
public class PRED_close_2 extends Predicate.P2 {
    private static final SymbolTerm SYM_ALIAS_1 = SymbolTerm.intern("alias", 1);
    private static final SymbolTerm SYM_FORCE_1 = SymbolTerm.intern("force", 1);
    private static final SymbolTerm SYM_TRUE    = SymbolTerm.intern("true");
    private static final SymbolTerm SYM_FALSE   = SymbolTerm.intern("false");

    public PRED_close_2(Term a1, Term a2, Operation cont) {
        arg1 = a1;
        arg2 = a2;
        this.cont = cont;
    }

    @Override
    public Operation exec(Prolog engine) {
        engine.requireFeature(Prolog.Feature.IO, this, arg1);
        engine.setB0();
        Term a1, a2;
        a1 = arg1;
        a2 = arg2;

	boolean forceFlag = false;
	Object stream = null;

	// close options
	a2 = a2.dereference();
	Term tmp = a2;
	while (! Prolog.Nil.equals(tmp)) {
	    if (tmp instanceof VariableTerm)
		throw new PInstantiationException(this, 2);
	    if (! (tmp instanceof ListTerm))
		throw new IllegalTypeException(this, 2, "list", a2);
	    Term car = ((ListTerm) tmp).car().dereference();
	    if (car instanceof VariableTerm)
		throw new PInstantiationException(this, 2);
	    if (car instanceof StructureTerm) {
		SymbolTerm functor = ((StructureTerm) car).functor();
		Term[] args = ((StructureTerm) car).args();
		if (functor.equals(SYM_FORCE_1)) {
		    Term bool = args[0].dereference();
		    if (bool.equals(SYM_TRUE))
			forceFlag = true;
		    else if (bool.equals(SYM_FALSE))
			forceFlag = false;
		    else 
			throw new IllegalDomainException(this, 2, "close_option", car);
		} else {
		    throw new IllegalDomainException(this, 2, "close_option", car);
		}
	    } else {
		throw new IllegalDomainException(this, 2, "close_option", car);
	    }
	    tmp = ((ListTerm) tmp).cdr().dereference();
	}
	//stream
	a1 = a1.dereference();
	if (a1 instanceof VariableTerm) {
	    throw new PInstantiationException(this, 1);
	} else if (a1 instanceof SymbolTerm) {
	    if (! engine.getStreamManager().containsKey(a1))
		throw new ExistenceException(this, 1, "stream", a1, "");
	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
	} else if (a1 instanceof JavaObjectTerm) {
	    stream = ((JavaObjectTerm) a1).object();
	} else {
	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
	}
	if (stream instanceof PushbackReader) {
	    PushbackReader in = (PushbackReader) stream;
	    try {
		in.close();
	    } catch (IOException e) {
		throw new TermException(new JavaObjectTerm(e));
	    }
	} else if (stream instanceof PrintWriter) {
	    PrintWriter out = (PrintWriter) stream;
	    try {
	      if (out.checkError()) {
	        if (! forceFlag) {
	          throw new SystemException("output stream error");
	        }
	      }
	    } finally {
	      out.flush();
	      out.close();
	    }
	} else {
	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
	}
	// delete associated entries from the stream manager
	HashtableOfTerm streamManager = engine.getStreamManager();
	if (a1 instanceof SymbolTerm) {
	    streamManager.remove(engine.getStreamManager().get(a1));
	    streamManager.remove(a1);
	} else if (a1 instanceof JavaObjectTerm) {
	    Term tmp2 = streamManager.get(a1);
	    while (! Prolog.Nil.equals(tmp2)) {
		Term car = ((ListTerm) tmp2).car().dereference();
		if (car instanceof StructureTerm) {
		    SymbolTerm functor = ((StructureTerm) car).functor();
		    Term[] args = ((StructureTerm) car).args();
		    if (functor.equals(SYM_ALIAS_1)) {
			Term alias = args[0].dereference();
			streamManager.remove(alias);
		    }
		}
		tmp2 = ((ListTerm) tmp2).cdr().dereference();
	    }
	    streamManager.remove(a1);
	} else {
	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
	}
        return cont;
    }
}
