package com.googlecode.prolog_cafe.builtin;
import com.googlecode.prolog_cafe.lang.*;
import java.io.*;
/**
 * <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;
    }

    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 (! tmp.isNil()) {
	    if (tmp.isVariable())
		throw new PInstantiationException(this, 2);
	    if (! tmp.isList())
		throw new IllegalTypeException(this, 2, "list", a2);
	    Term car = ((ListTerm) tmp).car().dereference();
	    if (car.isVariable())
		throw new PInstantiationException(this, 2);
	    if (car.isStructure()) {
		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.isVariable()) {
	    throw new PInstantiationException(this, 1);
	} else if (a1.isSymbol()) {
	    if (! engine.getStreamManager().containsKey(a1))
		throw new ExistenceException(this, 1, "stream", a1, "");
	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
	} else if (a1.isJavaObject()) {
	    stream = ((JavaObjectTerm) a1).object();
	} else {
	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
	}
	if (stream instanceof PushbackReader) {
	    PushbackReader in = (PushbackReader) stream;
	    if (in.equals(engine.getUserInput()))
		return cont;
	    if (in.equals(engine.getCurrentInput()))
		engine.setCurrentInput(engine.getUserInput());
	    try {
		in.close();
	    } catch (IOException e) {
		throw new TermException(new JavaObjectTerm(e));
	    }
	} else if (stream instanceof PrintWriter) {
	    PrintWriter out = (PrintWriter) stream;
	    if (out.checkError()) {
		if (! forceFlag)
		    throw new SystemException("output stream error");
	    }
	    out.flush();
	    if (out.equals(engine.getUserOutput()) || out.equals(engine.getUserError()))
		return cont;
	    if (out.equals(engine.getCurrentOutput()))
		engine.setCurrentOutput(engine.getUserOutput());
	    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.isSymbol()) {
	    streamManager.remove(engine.getStreamManager().get(a1));
	    streamManager.remove(a1);
	} else if (a1.isJavaObject()) {
	    Term tmp2 = streamManager.get(a1);
	    while (! tmp2.isNil()) {
		Term car = ((ListTerm) tmp2).car().dereference();
		if (car.isStructure()) {
		    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;
    }
}
