/*
 * Copyright 2013 Yuichiro Moriguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.morilib.bc;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.util.Iterator;

import net.morilib.dc.DcQuitSignalException;
import net.morilib.dc.DcSyntaxException;
import net.morilib.sh.ShEnvironment;
import net.morilib.sh.ShFileSystem;
import net.morilib.sh.ShProcess;
import net.morilib.unix.misc.OptionIterator;

/**
 * 
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/07/14
 */
public final class Bc implements ShProcess {

	static void readlib(InputStream ins, BcParser p,
			BcNamespace ns) {
		Reader rd;

		try {
			rd  = new InputStreamReader(ins);
			p.run(rd, ns, -1);
		} catch(Exception e) {
			throw new RuntimeException(e);
		} finally {
			if(ins != null) {
				try {
					ins.close();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

	static void readMathlib(BcParser p, BcNamespace ns) {
		readlib(Bc.class.getResourceAsStream(
					"/net/morilib/bc/math.bc"), p, ns);
	}

	/* (non-Javadoc)
	 * @see net.morilib.sh.ShProcess#main(net.morilib.sh.ShEnvironment, net.morilib.sh.ShFileSystem, java.io.InputStream, java.io.PrintStream, java.io.PrintStream, java.lang.String[])
	 */
	public int main(ShEnvironment env, ShFileSystem fs, InputStream in,
			PrintStream out, PrintStream err,
			String... args) throws IOException {
		String[] a = new String[args.length - 1];
		BcNamespace ns = new BcRootNamespace();
		Iterator<String> t;
		OptionIterator o;
		BcParser p;
		String s;

		System.arraycopy(args, 1, a, 0, a.length);
		p = new BcParser(in, out);
		o = new OptionIterator("l", a);
		while(o.hasNext()) {
			switch(o.nextChar()) {
			case 'l':  readMathlib(p, ns);  break;
			}
		}

		t = o.filenameIterator();
		try {
			if(t.hasNext()) {
				while(t.hasNext()) {
					s = t.next();
					readlib(fs.getFile(s).getInputStream(), p, ns);
				}
			} else {
				while(true) {
					try {
						p.run(new InputStreamReader(in),
								ns,
								0);
					} catch(BcSyntaxException e) {
						e.printStackTrace(err);
					} catch(DcSyntaxException e) {
						e.printStackTrace(err);
					} catch(ArithmeticException e) {
						e.printStackTrace(err);
					}
				}
			}
		} catch(BcQuitException e) {
			// do nothing
		} catch(DcQuitSignalException e) {
			// do nothing
		}
		return 0;
	}

}
