/*******************************************************************************
 * Copyright (c) 2009, 2019 Xored Software Inc 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
 * https://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.core.persistence;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.rcptt.core.workspace.Q7Utils;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.util.FileUtil;
import org.eclipse.rcptt.util.StreamUtil;

public abstract class BasePersistenceModel implements IPersistenceModel {

	protected final Map<String, File> files = new HashMap<String, File>();

	protected abstract void doExtractAll(InputStream contents)
			throws IOException;

	protected abstract void doExtractFile(String fName, InputStream contents)
			throws IOException;

	protected abstract void doReadIndex(InputStream contents);

	protected abstract void doStoreTo(File file) throws FileNotFoundException,
			IOException;

	protected final Resource element;
	protected final File root;
	protected final IPath rootPath;
	private boolean modified = false;
	private byte[] internalContent = null;
	private Set<String> extractions = new HashSet<String>();
	private boolean disposed = false;

	public boolean isContentEntryRequired() {
		return true;
	}

	public boolean isAllowEmptyMetadataContent() {
		return false;
	}

	public BasePersistenceModel(Resource element) {
		this.element = element;
		IPath nonExistent = null;
		while (true) {
			RcpttPlugin default1 = RcpttPlugin.getDefault();
			assert default1 != null;
			String uri = (element == null || element.getURI() == null) ? "_"
					: element.getURI().toString();
			nonExistent = default1
					.getStateLocation()
					.append("attachments")
					.append(FileUtil.limitSize(FileUtil.getID(uri))
							+ System.currentTimeMillis());
			if (!nonExistent.toFile().exists()) {
				break;
			}
		}
		assert nonExistent != null;
		rootPath = nonExistent;
		this.root = rootPath.toFile();
		// Make index
		try {
			readIndex();
		} catch (CoreException e) {
			RcpttPlugin.log(e);
		}
	}

	public Resource getResource() {
		return this.element;
	}

	public void setInternalContent(byte[] internalContent) {
		this.internalContent = internalContent;
		try {
			readIndex();
		} catch (CoreException e) {
			RcpttPlugin.log(e);
		}
	}

	private void initialize() {
		assert !disposed;
		root.mkdirs();
	}

	public boolean hasElements() {
		return !files.isEmpty();
	}

	public String[] getNames() {
		return files.keySet().toArray(new String[files.size()]);
	}

	private void readIndex() throws CoreException {
		assert !disposed;
		InputStream contents = getContentsStream();
		if (contents == null) {
			return;
		}
		try {
			doReadIndex(contents);
		} finally {
			try {
				contents.close();
			} catch (IOException e) {
			}
		}
	}

	protected InputStream getContentsStream() {
		InputStream input = null;
		IFile file = element != null ? Q7Utils.getLocation(element) : null;
		if (file != null && !file.exists()) {
			return null;
		}
		if (internalContent != null) {
			input = new ByteArrayInputStream(internalContent);
		}

		InputStream contents;
		try {
			if (input == null && file == null) {
				return null;
			}
			if (input == null) {
				input = file.getContents();
			}
			contents = new BufferedInputStream(input);
		} catch (CoreException e) {
			// Ignore file not found exception
			if (e.getStatus().getCode() != 271) {
				RcpttPlugin.log(e);
			}
			return null;
		}
		return contents;
	}

	protected File putFileItem(String name, IPath filePath) {
		return files.put(name, filePath.toFile());
	}

	public void dispose() {
		if (disposed)
			return;
		removeAll();
		disposed = true;
	}

	public InputStream read(String name) {
		assert !disposed;
		File file = files.get(name);
		if (file == null) {
			return null;
		}
		waitUntilExtracted(name);
		if (!file.exists()) {
			extractFile(name);
			waitUntilExtracted(name);
		}
		if (file.exists()) {
			try {
				return getInput(file);
			} catch (FileNotFoundException e) {
				RcpttPlugin.log(e);
			}
		}

		return null;
	}

	private void waitUntilExtracted(String name) {
		synchronized (extractions) {
			while (extractions.contains(name)) {
				try {
					extractions.wait(100);
				} catch (InterruptedException e) {
					RcpttPlugin.log(e);
				}
			}
		}
	}

	protected BufferedInputStream getInput(File file)
			throws FileNotFoundException {
		return new BufferedInputStream(new FileInputStream(file));
	}

	private void extractFile(String fName) {
		initialize();
		InputStream contents = null;
		try {
			synchronized (extractions) {
				if (extractions.contains(fName)) {
					return;
				}
				extractions.add(fName);
			}
			contents = getContentsStream();
			if (contents == null) {
				return;
			}
			doExtractFile(fName, contents);
		} catch (Throwable e1) {
			RcpttPlugin.log(e1);
		} finally {
			synchronized (extractions) {
				extractions.remove(fName);
				extractions.notifyAll();
			}
			try {
				if (contents != null) {
					contents.close();
				}
			} catch (IOException e) {
			}
		}
	}

	public void delete(String name) {
		File file = files.get(name);
		if (file != null && file.exists()) {
			file.delete();
		}
		files.remove(name);
	}

	public boolean restore(String name) {
		File file = files.get(name);
		if (file != null && file.exists()) {
			file.delete();
			extractFile(name);
			return file.exists();
		}
		return false;
	}

	public OutputStream store(String name) {
		modified = true;
		return internalStore(name);
	}

	protected OutputStream internalStore(String name) {
		initialize();
		IPath path = rootPath.append(new Path(name));
		File file = path.toFile();
		file.getParentFile().mkdirs();
		files.put(name, file);
		try {
			return new BufferedOutputStream(new FileOutputStream(file));
		} catch (FileNotFoundException e) {
			RcpttPlugin.log(e);
			return null;
		}
	}

	public void extractAll() {
		initialize();

		InputStream contents = null;
		try {
			contents = getContentsStream();
			if (contents == null) {
				return;
			}
			doExtractAll(contents);
		} catch (Throwable e1) {
			RcpttPlugin.log(e1);
		} finally {
			try {
				if (contents != null) {
					contents.close();
				}
			} catch (IOException e) {
			}
		}
	}

	public File storeToTemporaty() {
		initialize();

		File file = rootPath.append(
				".q7.content.temporary" + System.currentTimeMillis()).toFile();
		try {
			doStoreTo(file);
		} catch (Exception e) {
			RcpttPlugin.log(e);
		}
		return file;
	}

	public void removeAll() {
		files.clear();
		if (root != null) {
			FileUtil.deleteFiles(root.listFiles());
			root.delete();
		}
	}

	/**
	 * Return true if some resources are copied. Copy all resources except
	 * PersistenceManager.CONTENT_ENTRY
	 */
	public boolean copyFrom(IPersistenceModel originalModel) {
		removeAll();
		String[] names = originalModel.getNames();
		for (String name : names) {
			InputStream inputStream = originalModel.read(name);
			OutputStream outputStream = store(name);
			try {
				FileUtil.copy(inputStream, outputStream);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return names.length > 0;
	}

	public boolean isModified() {
		return modified;
	}

	public void updateMetadata() {
	}

	public void updateAttributes() {
	}

	public void setUnmodified() {
		modified = false;
	}

	public int size(String teslaContentEntry) {
		InputStream stream = read(teslaContentEntry);
		int result = 0;
		if (stream != null) {
			try {

				byte[] buffer = new byte[4096];
				int len = 0;
				while ((len = stream.read(buffer)) > 0) {
					result += len;
				}
			} catch (IOException e) {
				result = 0;
			} finally {
				StreamUtil.closeSilently(stream);
			}
		}
		return result;
	}

	public void rename(String oldName, String newName) {
		InputStream read = read(oldName);
		if (read != null) {
			OutputStream store = store(newName);
			try {
				FileUtil.copy(read, store);
				delete(oldName);
			} catch (IOException e) {
				RcpttPlugin.log(e);
			}
		}
	}
}
