/*******************************************************************************
 * Copyright (c) 2007, 2008 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.wst.validation.internal;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
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.osgi.util.NLS;
import org.eclipse.wst.validation.DependentResource;
import org.eclipse.wst.validation.IDependencyIndex;
import org.eclipse.wst.validation.Validator;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

/**
 * A simple implementation of the IDependencyIndex. This will probably be
 * replaced with a higher performance, more robust index, at some point in the
 * future.
 * <p>
 * The format of the index is:
 * 
 * <pre>
 * Version number
 * Number of depends on entries
 *   depends on file name
 *   number of dependent entries
 *     dependent file name
 *     number of validators
 *       validator id
 * </pre>
 * 
 * @author karasiuk
 */
public class DependencyIndex implements IDependencyIndex, ISaveParticipant {
	
	/**
	 * An index so that we can determine which things depend on this resource.
	 */
	private Map<IResource,Set<Depends>>		_dependsOn;
	
	/**
	 * An index so that we can determine who the resource depends on.
	 */
	private Map<IResource,Set<Depends>>		_dependents;
	private boolean _dirty;
	
	private static IResource[] EmptyResources = new IResource[0];
	
	/** Version of the persistent index. */
	private static final int CurrentVersion = 1;

	public synchronized void add(String id, IResource dependent, IResource dependsOn) {
		init();
		if (dependsOn == null || dependent == null)return;
		Depends d = getOrCreateDepends(dependent, dependsOn);
		if (d.getValidators().add(id))_dirty = true;
	}
	
	private Depends getOrCreateDepends(IResource dependent, IResource dependsOn) {
		Set<Depends> set = getSet(_dependents, dependent);
		for (Depends d : set){
			if (d.getDependsOn().equals(dependsOn)) return d;
		}
		Depends d = new Depends(dependent, dependsOn);
		_dirty = true;
		set.add(d);
		
		getSet(_dependsOn, dependsOn).add(d);
		return d;
	}

	/**
	 * Answer the set for the resource, creating it if you need to.
	 */
	private Set<Depends> getSet(Map<IResource, Set<Depends>> map, IResource resource) {
		Set<Depends> set = map.get(resource);
		if (set == null){
			set = new HashSet<Depends>(5);
			map.put(resource, set);
		}
		return set;
	}

	/**
	 * Restore the dependency index. See the class comment for the structure.
	 */	
	private void init() {
		if (_dependsOn != null)return;
		
		boolean error = false;
		File f = getIndexLocation();
		if (!f.exists()){
			_dependsOn = new HashMap<IResource,Set<Depends>>(100);
			_dependents = new HashMap<IResource,Set<Depends>>(100);
		}
		else {
			String errorMessage = "The following dependency could not be restored " + 
				"because the following resource {0} could no longer be found."; 
			DataInputStream in = null;
			try {
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				in = new DataInputStream(new FileInputStream(f));
				
				int version = in.readInt();
				if (version != CurrentVersion){
					error = true;
					String msg = NLS.bind(ValMessages.ErrDependencyVersion, CurrentVersion);
					throw new IllegalStateException(msg);
				}
				int numDependsOn = in.readInt();
				_dependsOn = new HashMap<IResource,Set<Depends>>(numDependsOn+100);
				_dependents = new HashMap<IResource,Set<Depends>>(numDependsOn+100);
				for (int i=0; i<numDependsOn; i++){
					String v = in.readUTF();
					IResource dependsOn = root.findMember(v);
					if (dependsOn == null){
						Tracing.log(NLS.bind(errorMessage, v));
						continue;
					}
					int numDependents = in.readInt();
					for (int j=0; j<numDependents; j++){
						v = in.readUTF();
						IResource dependent = root.findMember(v);
						if (dependent == null){
							Tracing.log(NLS.bind(errorMessage, v));
							continue;
						}
						int numVal = in.readInt();
						for (int k=0; k<numVal; k++){
							String id = in.readUTF();
							add(id, dependent, dependsOn);
						}
					}					
				}				
			}
			catch (IOException e){
				error = true;
				ValidationPlugin.getPlugin().handleException(e);
			}
			finally {
				Misc.close(in);
				if (error){
					_dependsOn = new HashMap<IResource,Set<Depends>>(100);
					_dependents = new HashMap<IResource,Set<Depends>>(100);
					f.delete();
				}
			}			
		}
	}

	public synchronized void clear(IProject project) {
		init();
		for (Map.Entry<IResource,Set<Depends>> me : _dependents.entrySet()){
			if (me.getKey().getProject() == project){
				for (Depends d : me.getValue()){
					if (d.delete())_dirty = true;
				}
			}
		}
	}

	public synchronized IResource[] get(String validatorId, IResource dependsOn) {
		init();
		List<IResource> list = new LinkedList<IResource>();
		Set<Depends> set = getSet(_dependsOn, dependsOn);
		for (Depends d : set){
			for (String id : d.getValidators()){
				if (validatorId.equals(id))list.add(d.getDependent());
			}
		}
		
		if (list.size() == 0)return EmptyResources;
		IResource[] resources = new IResource[list.size()];
		list.toArray(resources);
		return resources;
	}

	
	public synchronized List<DependentResource> get(IResource dependsOn) {
		init();
		List<DependentResource> list = new LinkedList<DependentResource>();
		Set<Depends> set = getSet(_dependsOn, dependsOn);
		ValManager vm = ValManager.getDefault();
		for (Depends d : set){
			for (String id : d.getValidators()){
				Validator v = vm.getValidator(id, d.getDependent().getProject());
				if (v != null)list.add(new DependentResource(d.getDependent(), v));
			}
		}
		return list;
	}


	public synchronized void set(String id, IResource dependent, IResource[] dependsOn) {
		init();
		Set<Depends> set = getSet(_dependents, dependent);
		for (Depends d : set){
			if (d.delete(id))_dirty = true;
		}
		if (dependsOn != null){
			for (IResource d : dependsOn)add(id, dependent, d);
		}
	}
		
	public boolean isDependedOn(IResource resource) {
		init();
		Set<Depends> set = _dependsOn.get(resource);
		if (set == null || set.size() == 0)return false;
		return true;
	}

	public void doneSaving(ISaveContext context) {	
	}
	
	public void prepareToSave(ISaveContext context) throws CoreException {	
	}
	
	public void rollback(ISaveContext context) {
	}
	
	/**
	 * Persist the dependency index. See the class comment for the structure.
	 */
	public synchronized void saving(ISaveContext context) throws CoreException {
		if (!_dirty)return;
		_dirty = false;
		
		DataOutputStream out = null;
		try {
			File f = getIndexLocation();
			out = new DataOutputStream(new FileOutputStream(f));
			out.writeInt(CurrentVersion);
			Map<String, Set<DependsResolved>> map = compress(_dependsOn);
			out.writeInt(map.size());
			for (Map.Entry<String, Set<DependsResolved>> me : map.entrySet()){
				out.writeUTF(me.getKey());
				Set<DependsResolved> set = me.getValue();
				out.writeInt(set.size());
				for (DependsResolved d : set){
					out.writeUTF(d.resource);
					out.writeInt(d.validators.size());
					for (String id : d.validators){
						out.writeUTF(id);
					}
				}
			}
		}
		catch (IOException e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		finally {
			Misc.close(out);
		}
	}

	private Map<String, Set<DependsResolved>> compress(Map<IResource, Set<Depends>> dependsOn) {
		Map<String, Set<DependsResolved>> map = new HashMap<String, Set<DependsResolved>>(dependsOn.size());
		for (Map.Entry<IResource, Set<Depends>> me : dependsOn.entrySet()){
			Set<DependsResolved> set = new HashSet<DependsResolved>(me.getValue().size());
			for (Depends d : me.getValue()){
				IPath path = d.getDependent().getFullPath();
				if (path != null){
					DependsResolved dr = new DependsResolved();
					dr.resource = path.toPortableString();
					if (d.getValidators().size() > 0){
						dr.validators = d.getValidators();
						set.add(dr);
					}
				}				
			}
			if (set.size() > 0){
				IResource res = me.getKey();
				if (res != null){
					IPath path = res.getFullPath();
					if (path != null)map.put(path.toPortableString(), set);
				}
			}
		}
		return map;
	}

	private File getIndexLocation() {
		IPath path = ValidationPlugin.getPlugin().getStateLocation().append("dep.index"); //$NON-NLS-1$
		return path.toFile();
	}

	/**
	 * Keep track of a relationship between a dependent and the thing that it
	 * depends on.
	 * 
	 * @author karasiuk
	 * 
	 */
	private static class Depends {

		/** The resource that is being depended on, for example a.xsd */
		private IResource _dependsOn;

		/** The resource that is dependent, for example a.xml */
		private IResource _dependent;

		/** The id's of the validators that have asserted the dependency. */
		private Set<String> _validators;

		public Depends(IResource dependent, IResource dependsOn) {
			_dependent = dependent;
			_dependsOn = dependsOn;
			_validators = new HashSet<String>(5);
		}

		/**
		 * Answer true if the id was deleted.
		 */
		public boolean delete(String id) {
			return _validators.remove(id);
		}

		/**
		 * Delete all the dependency assertions for all of your validators.
		 * @return false if there was nothing to delete
		 */
		public boolean delete() {
			boolean deleted = _validators.size() > 0;
			if (deleted)_validators.clear();
			return deleted;
		}

		public IResource getDependsOn() {
			return _dependsOn;
		}

		public IResource getDependent() {
			return _dependent;
		}

		public Set<String> getValidators() {
			return _validators;
		}
}

	private static class DependsResolved {
		String 		resource;
		Set<String> validators;
	}


}
