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

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import net.morilib.sh.ShFile;
import net.morilib.sh.ShFileSystem;
import net.morilib.sh.ShSecurityPolicy;

public class ShUnixFileSystem implements ShFileSystem {

	private String home;
	private ShFile realcur;
	private ShSecurityPolicy security;

	public ShUnixFileSystem(String home, ShSecurityPolicy security) {
		this.home = home;
		this.security = security;
	}

	public ShFile getCurrentDirectory() {
		return realcur;
	}

	public void setCurrentDirectory(ShFile s) {
		realcur = s;
	}

	public ShFile getFile(String s) {
		String t, v;

		t = s.replaceFirst("^/+", "/");
		t = t.replaceFirst("/+$", "");
		t = t.replaceAll("^(/\\.\\.)+", "/");
		do {
			v = t;
			t = t.replaceAll("/[^/]+/\\.\\.", "");
		} while(!t.equals(v));
		t = t.replaceAll("(/\\.)+/", "/");
		t = t.replaceAll("(/\\.)+$", "");
		if(t.length() == 0) {
			return getCurrentDirectory();
		} else if(t.charAt(0) == '/') {
			return new ShUnixRealFile(this, t, new File(t));
		} else if(getCurrentDirectory().toString().equals("/")) {
			return new ShUnixRealFile(this, "/" + t, new File("/", t));
		} else {
			return new ShUnixRealFile(this,
					getCurrentDirectory() + "/" + t,
					new File(getCurrentDirectory().toString(), t));
		}
	}

	public ShFile getFile(String dir, String name) {
		return getFile(dir + "/" + name);
	}

	public ShFile getFile(ShFile dir, String name) {
		return getFile(dir.toString() + "/" + name);
	}

	public ShFile getRoot() {
		return new ShUnixRealFile(this, "/", new File("/"));
	}

	public ShSecurityPolicy getSecurityPolicy() {
		return security;
	}

	public InputStream getProfile() {
		ShFile f;

		try {
			if((f = getFile(home, ".jsh_profile")).isFile() ||
					(f = getFile(home, ".jsh_login")).isFile() ||
					(f = getFile(home, ".profile")).isFile()) {
				return f.getInputStream();
			} else {
				return null;
			}
		} catch (IOException e) {
			return null;
		}
	}

	public InputStream getRc() {
		ShFile f;

		try {
			if((f = getFile(home, ".jshrc")).isFile()) {
				return f.getInputStream();
			} else {
				return null;
			}
		} catch (IOException e) {
			return null;
		}
	}

	public ShFile getHome() {
		return getFile(home);
	}

}
