/*
 * 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.sh.builtin;

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

import net.morilib.sh.ShEnvironment;
import net.morilib.sh.ShFileSystem;
import net.morilib.sh.ShProcess;

/**
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/05/26
 */
public class ShRead implements ShProcess {

	private void addifs(ShEnvironment env, StringBuffer b,
			int k, String... args) {
		String s = env.find("IFS");

		s = s == null || s.equals("") ? " " : s;
		if(b.length() > 0 && k >= args.length - 1) {
			b.append(s.charAt(0));
		}
	}

	/* (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 stdin, PrintStream out, PrintStream err,
			String... args) throws IOException {
		Reader in = new InputStreamReader(stdin, env.getCharset());
		StringBuffer b = new StringBuffer();
		String s, ifs = env.find("IFS");
		boolean sep = true, r;
		int k, c;

		k = (r = args.length > 1 && args[1].equals("-r")) ? 2 : 1;
		while((c = in.read()) >= 0) {
			if(sep) {
				if(c == '\n') {
					for(; k < args.length - 1; k++) {
						env.bind(args[k], "");
						b = new StringBuffer();
					}
					break;
				} else if(!r && c == '\\') {
					if((c = in.read()) < 0) {
						break;
					} else if(c == '\r' &&
							(c = in.read()) != '\n') {
						b.append((char)c);
					} else if(c != '\n') {
						b.append((char)c);
					}
				} else if(c != '\r' && ifs.indexOf(c) < 0) {
					addifs(env, b, k, args);
					b.append((char)c);
					sep = false;
				} else if(c != '\r') {
					// do nothing
				} else if((c = in.read()) < 0 || c == '\n') {
					for(; k < args.length - 1; k++) {
						env.bind(args[k], "");
						b = new StringBuffer();
					}
					break;
				} else {
					b.append('\r');
					b.append((char)c);
					sep = false;
				}
			} else {
				if(c == '\n') {
					for(; k < args.length - 1; k++) {
						s = b.toString();
						env.bind(args[k], s);
						b = new StringBuffer();
					}
					break;
				} else if(!r && c == '\\') {
					if((c = in.read()) < 0) {
						break;
					} else if(c == '\r' &&
							(c = in.read()) != '\n') {
						b.append((char)c);
					} else if(c != '\n') {
						b.append((char)c);
					}
				} else if(c != '\r' && ifs.indexOf(c) >= 0) {
					if(k < args.length - 1) {
						s = b.toString();
						env.bind(args[k++], s);
						b = new StringBuffer();
					}
					sep = true;
				} else if(c != '\r') {
					b.append((char)c);
				} else if((c = in.read()) < 0 || c == '\n') {
					for(; k < args.length - 1; k++) {
						s = b.toString();
						env.bind(args[k], s);
						b = new StringBuffer();
					}
					break;
				} else {
					b.append('\r');
					b.append((char)c);
				}
			}
		}
		s = b.toString();
		if(args.length > k)  env.bind(args[k], s);
		return 0;
	}

}
