/*******************************************************************************
 * Copyright (c) 2003, 2007 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.jst.j2ee.internal.archive;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jst.j2ee.internal.archive.operations.EJBArchiveOpsResourceHandler;
import org.eclipse.jst.j2ee.internal.archive.operations.IOverwriteHandler;
import org.eclipse.jst.j2ee.internal.archive.operations.OverwriteHandlerException;
import org.eclipse.jst.jee.archive.AbstractArchiveSaveAdapter;
import org.eclipse.jst.jee.archive.ArchiveSaveFailureException;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveResource;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.datamodel.properties.ICreateReferenceComponentsDataModelProperties;
import org.eclipse.wst.common.componentcore.internal.operation.CreateReferenceComponentsDataModelProvider;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;

// hari: make abstract
public class ComponentArchiveSaveAdapter extends AbstractArchiveSaveAdapter {

	protected IDataModel dataModel;

	protected IVirtualComponent vComponent;

	protected IOverwriteHandler overwriteHandler;

	protected IProgressMonitor progressMonitor;

	private String archiveComponentsDeployPath;

	private List archiveComponents;

	private Map archiveComponentURIMap;

	public ComponentArchiveSaveAdapter(IVirtualComponent vComponent) {
		super();
		if (null == vComponent) {
			throw new NullPointerException();
		}
		this.vComponent = vComponent;
	}

	public void setDataModel(IDataModel dataModel) {
		this.dataModel = dataModel;
	}

	public void setOverwriteHandler(IOverwriteHandler newOverwriteHandler) {
		overwriteHandler = newOverwriteHandler;
	}

	public void setProgressMonitor(IProgressMonitor newProgressMonitor) {
		progressMonitor = newProgressMonitor;
	}

	protected void validateEdit(IFile aFile) {
		if (overwriteHandler == null)
			return;
		if (!(aFile.exists() && aFile.isReadOnly()))
			return;

		overwriteHandler.validateEdit(aFile);
	}

	protected boolean shouldOverwrite(String uri) {
		if (overwriteHandler.isOverwriteNone())
			return false;
		return (overwriteHandler.isOverwriteResources() || overwriteHandler.isOverwriteAll() || overwriteHandler.shouldOverwrite(uri));
	}

	protected OutputStream getOutputStreamForResource(Resource aResource) throws IOException {
		// this method has no references in the hirarchy
		return null;
	}

	@Override
	public void save(IProgressMonitor monitor) throws ArchiveSaveFailureException {
		final int SUPER_TICKS = 1000;
		final int LOCAL_TICKS = 10;
		final int TOTAL_TICKS = SUPER_TICKS + LOCAL_TICKS;
		try {
			monitor.beginTask(NLS.bind(ArchiveMessages.ComponentArchiveSaveAdapter_Importing_0_, vComponent.getName()), TOTAL_TICKS);
			super.save(new SubProgressMonitor(monitor, SUPER_TICKS));
			linkArchiveComponents();
			monitor.worked(LOCAL_TICKS);
		} finally {
			monitor.done();
		}
	}

	@Override
	public void save(IArchiveResource aFile) throws ArchiveSaveFailureException {

		try {
			if (progressMonitor == null)
				progressMonitor = new NullProgressMonitor();
			progressMonitor.subTask(aFile.getPath().toString());
			InputStream in = aFile.getInputStream();
			
			IPath projectRelativePath = getProjectRelativePath(aFile);
			if (aFile.getType() == IArchiveResource.ARCHIVE_TYPE) {
				saveAsArchiveComponent((IArchive) aFile, projectRelativePath, in);
			} else if (aFile.getType() != IArchiveResource.DIRECTORY_TYPE) {
				saveToOutputPath(projectRelativePath, in);
			} else {
				createDirectory(projectRelativePath);
			}
		} catch (OverwriteHandlerException ohe) {
			throw ohe;
		} catch (Exception e) {
			String errorString = EJBArchiveOpsResourceHandler.ARCHIVE_OPERATION_SaveFile + aFile.getPath();
			throw new ArchiveSaveFailureException(errorString);
		} finally {
			if(null != progressMonitor){
				progressMonitor.worked(1);
			}
		}
	}

	/**
	 * Returns the project relative path for where the specified file should be
	 * saved.
	 * 
	 * @param aFile
	 * @return
	 */
	protected IPath getProjectRelativePath(IArchiveResource aFile) {
		IPath path = aFile.getPath();
		IFile iFile = null;
		if (path.segmentCount() > 0 && path.segment(0).equals(IModuleConstants.DOT_SETTINGS)) {
			iFile = vComponent.getProject().getFile(path);
		} else {
			IVirtualFolder rootFolder = vComponent.getRootFolder();
			IVirtualFile vFile = rootFolder.getFile(path);
			iFile = vFile.getUnderlyingFile();
		}
		return iFile.getProjectRelativePath();
	}

	/**
	 * Creates the IFolder specified by the project relative path.
	 * 
	 * @param projectRelativePath
	 * @throws CoreException
	 */
	protected void createDirectory(IPath projectRelativePath) throws CoreException {
		IFolder iFolder = vComponent.getProject().getFolder(projectRelativePath);
		if (!iFolder.exists()) {
			mkdirs(iFolder);
		}
	}

	/**
	 * Creates the specified IFolder
	 * 
	 * @param folder
	 * @throws CoreException
	 */
	protected void mkdirs(IFolder folder) throws CoreException {
		IContainer container = folder.getParent();
		if (!container.exists()) {
			mkdirs((IFolder) container);
		}
		folder.create(true, true, null);
	}

	/**
	 * Save the specified Archive to the specified project relative path using
	 * the passed input stream.
	 * 
	 * @param archive
	 * @param projectRelativePath
	 * @param in
	 * @throws Exception
	 */
	protected void saveAsArchiveComponent(IArchive archive, IPath projectRelativePath, InputStream in) throws Exception {
		IFile iFile = saveToOutputPath(projectRelativePath, in);
		// TODO investigate removing this block and related variables and
		// linkArchiveComponents(); see bugzilla 159160
		if (shouldLinkAsComponentRef(archive)) {
			IVirtualComponent archiveComponent = ComponentCore.createArchiveComponent(vComponent.getProject(), VirtualArchiveComponent.LIBARCHIVETYPE + iFile.getFullPath().toString());
			if (archiveComponents == null) {
				archiveComponents = new ArrayList();
				archiveComponentURIMap = new HashMap();
				archiveComponentsDeployPath = IPath.SEPARATOR + projectRelativePath.removeLastSegments(1).toString();
			}
			archiveComponents.add(archiveComponent);
			archiveComponentURIMap.put(archiveComponent, iFile.getName());
		}
	}

	protected boolean shouldLinkAsComponentRef(IArchive archive) {
		return false;
	}

	protected void linkArchiveComponents() {
		if (archiveComponents != null && archiveComponents.size() > 0) {
			IDataModel createReferencesDataModel = DataModelFactory.createDataModel(new CreateReferenceComponentsDataModelProvider());
			createReferencesDataModel.setProperty(ICreateReferenceComponentsDataModelProperties.SOURCE_COMPONENT, vComponent);
			createReferencesDataModel.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_DEPLOY_PATH, archiveComponentsDeployPath);
			createReferencesDataModel.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENT_LIST, archiveComponents);
			createReferencesDataModel.setProperty(ICreateReferenceComponentsDataModelProperties.TARGET_COMPONENTS_TO_URI_MAP, archiveComponentURIMap);
			try {
				createReferencesDataModel.getDefaultOperation().execute(null, null);
			} catch (ExecutionException e) {
				J2EEPlugin.logError(e);
			}
		}
	}

	/**
	 * Saves to the specified project relative output path. Warning this method
	 * will be changed post 1.5 to return an IFile
	 * 
	 * @param projectRelativePath
	 * @param in
	 * @throws Exception
	 */
	protected IFile saveToOutputPath(IPath projectRelativePath, InputStream in) throws Exception {
		IFile iFile = vComponent.getProject().getFile(projectRelativePath);
		saveToIFile(iFile, in);
		return iFile;
	}

	protected void saveToIFile(IFile iFile, InputStream in) throws Exception {
		validateEdit(iFile);
		if (iFile.exists())
			iFile.setContents(in, true, true, null);
		else {
			mkdirs(iFile.getFullPath().removeLastSegments(1), ResourcesPlugin.getWorkspace().getRoot());
			iFile.create(in, true, null);
		}
	}

	protected void mkdirs(IPath path, IWorkspaceRoot root) throws CoreException {
		if (path.segmentCount() <= 1)
			return;
		IFolder folder = root.getFolder(path);
		if (!folder.exists()) {
			mkdirs(path.removeLastSegments(1), root);
			folder.create(true, true, null);
		}
	}

}
