/*******************************************************************************
 * Copyright (c) 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.filesystem.memory;

import java.io.*;
import java.util.ArrayList;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.provider.FileInfo;
import org.eclipse.core.runtime.*;

/**
 * An in-memory file system.
 */
public class MemoryTree {
	static class DirNode extends Node {
		private final ArrayList children = new ArrayList();

		DirNode(Node parent, String name) {
			super(parent, name);
		}

		void add(Node child) {
			children.add(child);
		}

		public String[] childNames() {
			String[] names = new String[children.size()];
			for (int i = 0, imax = children.size(); i < imax; i++) {
				Node child = (Node) children.get(i);
				names[i] = child.getInfo(false).getName();
			}
			return names;
		}

		/**
		 * Returns the child with the given name, or null if not found.
		 * @param name
		 * @return
		 */
		Node getChild(String name) {
			for (int i = 0, imax = children.size(); i < imax; i++) {
				Node child = (Node) children.get(i);
				if (child.getInfo(false).getName().equals(name))
					return child;
			}
			return null;
		}

		protected void initializeInfo(FileInfo fileInfo) {
			super.initializeInfo(fileInfo);
			fileInfo.setDirectory(true);
		}

		boolean isFile() {
			return false;
		}

		void remove(String name) {
			Node child = getChild(name);
			if (child != null)
				children.remove(child);
		}

		public String toString() {
			return super.toString() + ' ' + children;
		}
	}

	static class FileNode extends Node {
		byte[] contents = EMPTY_CONTENTS;

		FileNode(Node parent, String name) {
			super(parent, name);
		}

		boolean isFile() {
			return true;
		}

		public InputStream openInputStream() {
			return new ByteArrayInputStream(contents);
		}

		public OutputStream openOutputStream(final int options) {
			return new ByteArrayOutputStream() {
				public void close() throws IOException {
					super.close();
					setContents(toByteArray(), options);
				}
			};
		}

		protected void setContents(byte[] bytes, int options) {
			if ((options & EFS.APPEND) != 0) {
				//create reference in case of concurrent modification
				byte[] oldContents = this.contents;
				byte[] newContents = new byte[oldContents.length + bytes.length];
				System.arraycopy(oldContents, 0, newContents, 0, oldContents.length);
				System.arraycopy(bytes, 0, newContents, oldContents.length, bytes.length);
				this.contents = newContents;
			} else
				this.contents = bytes;
			info.setLastModified(System.currentTimeMillis());
			((FileInfo) info).setLength(bytes.length);
		}
	}

	static abstract class Node extends PlatformObject {
		protected IFileInfo info;

		Node(Node parent, String name) {
			if (parent != null)
				((DirNode) parent).add(this);
			FileInfo fileInfo = new FileInfo(name);
			initializeInfo(fileInfo);
			this.info = fileInfo;
		}

		IFileInfo getInfo(boolean copy) {
			return (IFileInfo) (copy ? ((FileInfo) info).clone() : info);
		}

		protected void initializeInfo(FileInfo fileInfo) {
			fileInfo.setExists(true);
			fileInfo.setLastModified(System.currentTimeMillis());
		}

		abstract boolean isFile();

		void putInfo(IFileInfo newInfo, int options) {
			if ((options & EFS.SET_ATTRIBUTES) != 0) {
				for (int i = 0; i < ALL_ATTRIBUTES.length; i++)
					info.setAttribute(ALL_ATTRIBUTES[i], newInfo.getAttribute(ALL_ATTRIBUTES[i]));
			}
			if ((options & EFS.SET_LAST_MODIFIED) != 0) {
				info.setLastModified(newInfo.getLastModified());
			}
		}

		/**
		 * For debugging purposes only.
		 */
		public String toString() {
			return info.getName();
		}
	}

	static final int[] ALL_ATTRIBUTES = new int[] {EFS.ATTRIBUTE_ARCHIVE, EFS.ATTRIBUTE_EXECUTABLE, EFS.ATTRIBUTE_HIDDEN, EFS.ATTRIBUTE_READ_ONLY,};

	public static final MemoryTree TREE = new MemoryTree();

	static final byte[] EMPTY_CONTENTS = new byte[0];

	private static final String ROOT_NAME = "<root>";

	private Node root = new DirNode(null, ROOT_NAME);

	private MemoryTree() {
		// TREE singleton should be used rather than direct instantiation
	}

	public String[] childNames(IPath path) {
		Node node = findNode(path);
		if (node == null || node.isFile())
			return null;
		return ((DirNode) node).childNames();
	}

	public void delete(IPath path) {
		//cannot delete the root
		if (path.segmentCount() == 0)
			return;
		Node parent = findNode(path.removeLastSegments(1));
		if (parent == null || parent.isFile())
			return;
		((DirNode) parent).remove(path.lastSegment());

	}

	/**
	 * Deletes the entire memory tree. Used during debugging and testing only.
	 */
	public void deleteAll() {
		this.root = new DirNode(null, ROOT_NAME);
	}

	/**
	 * Returns the file info for the given path. Never returns null.
	 * @param path
	 * @return
	 */
	public synchronized IFileInfo fetchInfo(IPath path) {
		Node node = findNode(path);
		if (node == null)
			return new FileInfo(path.lastSegment());
		return node.getInfo(true);
	}

	/**
	 * Returns the node at the given path, or null if not found.
	 * 
	 * @param path
	 * @return
	 */
	private Node findNode(IPath path) {
		Node current = root;
		for (int i = 0, imax = path.segmentCount(); i < imax; i++) {
			if (current == null || current.isFile())
				return null;
			current = ((DirNode) current).getChild(path.segment(i));
		}
		return current;
	}

	public Node mkdir(IPath path, boolean deep) throws CoreException {
		Node dir = findNode(path);
		if (dir != null) {
			if (dir.isFile())
				Policy.error("A file exists with this name: " + path);
			return dir;
		}
		final IPath parentPath = path.removeLastSegments(1);
		Node parent = findNode(parentPath);
		if (parent != null) {
			if (parent.isFile())
				Policy.error("Parent is a file: " + path);
		} else {
			if (!deep)
				Policy.error("Parent does not exist: " + parentPath);
			parent = mkdir(parentPath, deep);
		}
		//create the child directory
		return new DirNode(parent, path.lastSegment());
	}

	public InputStream openInputStream(IPath path) throws CoreException {
		Node node = findNode(path);
		if (node == null)
			Policy.error("File not found: " + path);
		if (!node.isFile())
			Policy.error("Cannot open stream on directory: " + path);
		return ((FileNode) node).openInputStream();
	}

	public OutputStream openOutputStream(IPath path, int options) throws CoreException {
		Node node = findNode(path);
		//if we already have such a file, just open a stream on it
		if (node instanceof DirNode)
			Policy.error("Could not create file: " + path);
		if (node instanceof FileNode)
			return ((FileNode) node).openOutputStream(options);
		//if the parent exists we can create the file
		Node parent = findNode(path.removeLastSegments(1));
		if (!(parent instanceof DirNode))
			Policy.error("Could not create file: " + path);
		node = new FileNode(parent, path.lastSegment());
		return ((FileNode) node).openOutputStream(options);
	}

	public void putInfo(IPath path, IFileInfo info, int options) throws CoreException {
		Node node = findNode(path);
		if (node == null)
			Policy.error("File not found: " + path);
		node.putInfo(info, options);
	}
}
