/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.internal.emf.resource;


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.wst.common.internal.emf.plugin.EcoreUtilitiesPlugin;
import org.eclipse.wst.common.internal.emf.utilities.IDUtil;

public class ReferencedXMIResourceImpl extends CompatibilityXMIResourceImpl implements ReferencedResource {
	//TODO Add toString hook
	private static final String TO_STRING = "ReferencedXMIResource, file = "; //$NON-NLS-1$
	private static final String READ_COUNT_TO_STRING = " R= "; //$NON-NLS-1$
	private static final String WRITE_COUNT_TO_STRING = " W= "; //$NON-NLS-1$

	private int readReferenceCount = 1;
	private int editReferenceCount = 0;
	protected boolean isNew = true;
	protected boolean forceRefresh;
	
	  public static class ESynchronizedAdapterList extends EAdapterList
	  {

	    /**
		 * 
		 */
		private static final long serialVersionUID = 7855438339187540718L;

		public ESynchronizedAdapterList(Notifier notifier) {
			super(notifier);
		}

		@Override
		public synchronized boolean add(Object object)
	    {
	    return super.add(object);
	    }

	    @Override
		public synchronized void add(int index, Object object)
	    {
	    super.add(index, object);
	    }

	    @Override
		public synchronized boolean addAll(Collection collection)
	    {
	    return super.addAll(collection);
	    }

	    @Override
		public synchronized boolean remove(Object object)
	    {
	    return super.remove(object);
	    }

	    @Override
		public synchronized Object remove(int index)
	    {
	    return super.remove(index);
	    }

	    @Override
		public synchronized boolean removeAll(Collection collection)
	    {
	    return super.removeAll(collection);
	    }

	    @Override
		public synchronized void clear()
	    {
	     super.clear();
	    }


	    @Override
		public synchronized Object set(int index, Object object)
	    {
	    return super.set(index, object);
	    }

	    @Override
		public synchronized void move(int newPosition, Object object)
	    {
	    super.move(newPosition, object);
	    }

	    @Override
		public synchronized Object move(int newPosition, int oldPosition)
	    {
	    return super.move(newPosition, oldPosition);
	    }
	  }

	 
	/**
	 * ReferencableXMIResourceImpl constructor comment.
	 */
	public ReferencedXMIResourceImpl() {
		super();
	}

	public ReferencedXMIResourceImpl(URI uri) {
		super(uri);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.internal.emf.resource.ReferencedResource#getReadCount()
	 */
	@Override
	public int getReadCount() {
		return readReferenceCount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.internal.emf.resource.ReferencedResource#getWriteCount()
	 */
	@Override
	public int getWriteCount() {
		return editReferenceCount;
	}



	/*
	 * @see ReferencedResource#accessForRead
	 */
	@Override
	public void accessForRead() {
		checkDeleted();
		if (!isNew())
			readReferenceCount++;
		isNew = false;
	}

	/*
	 * @see ReferencedResource#accessForWrite
	 */
	@Override
	public void accessForWrite() {
		checkDeleted();
		editReferenceCount++;
		if (isNew)
			releaseFromRead();
		isNew = false;
		if (!isTrackingModification())
			setTrackingModification(true);
	}

	/*
	 * Check if this resource has been removed and throw an exception if it does not have a
	 * ResourceSet.
	 */
	protected void checkDeleted() {
		if (getResourceSet() == null)
			throw new RuntimeException(DELETED_ERROR_MSG);
	}

	/**
	 *  
	 */
	public void collectContainedObjects(java.util.List collecting, EObject parentObject) {

		java.util.Iterator children = parentObject.eContents().iterator();
		while (children.hasNext()) {
			EObject child = (EObject) children.next();
			collecting.add(child);
			collectContainedObjects(collecting, child);
		}
	}

	/**
	 *  
	 */
	public void ensureFullIDHydration() {
		List allRefObjects = new ArrayList();
		Iterator rootObjects = getContents().iterator();
		while (rootObjects.hasNext()) {
			EObject child = (EObject) rootObjects.next();
			allRefObjects.add(child);
			collectContainedObjects(allRefObjects, child);
		}

		Iterator iter = allRefObjects.iterator();
		while (iter.hasNext())
			IDUtil.assignID((EObject) iter.next(), this);
	}

	/**
	 * If the resource is no longer being accessed, then remove it from the resource set.
	 */
	@Override
	public void unloadIfNecessary() {
		if ((getTotalReferenceCount() <= 0) || (editReferenceCount <= 0 && isModified()))
			unload();
	}

	/**
	 * Return the number of write accesses to this resource.
	 * 
	 * @return int The number of references.
	 */
	protected int getTotalReferenceCount() {
		return editReferenceCount + readReferenceCount;
	}

	/*
	 * @see ReferencedResource#isNew
	 */
	@Override
	public boolean isNew() {
		return isNew;
	}

	/*
	 * @see ReferencedResource#isReadOnly
	 */
	@Override
	public boolean isReadOnly() {
		return editReferenceCount <= 0;
	}

	/*
	 * @see ReferencedResource#isShared
	 */
	@Override
	public boolean isShared() {
		return getTotalReferenceCount() > 1;
	}

	/*
	 * @see ReferencedResource#isSharedForWrite
	 */
	@Override
	public boolean isSharedForWrite() {
		return editReferenceCount > 1;
	}

	/**
	 * @see ReferencedResource#preDelete
	 */
	public void preDelete() {
	}

	/*
	 * @see ReferencedResource#releaseFromRead
	 */
	@Override
	public void releaseFromRead() {
		readReferenceCount--;
		if (readReferenceCount < 0)
			throw new RuntimeException("Read reference count error:  " + this.toString()); //$NON-NLS-1$
		unloadIfNecessary();
	}

	/*
	 * @see ReferencedResource#releaseFromWrite
	 */
	@Override
	public void releaseFromWrite() {
		editReferenceCount--;
		if (editReferenceCount < 0)
			throw new RuntimeException("Write reference count error:  " + this.toString()); //$NON-NLS-1$
		unloadIfNecessary();
	}

	/*
	 * @see ReferencedResource#saveIfNecessary
	 */
	@Override
	public void saveIfNecessary() throws Exception {
		if (!isSharedForWrite()) // caller is the only referencer
			save(Collections.EMPTY_MAP);
	}

	@Override
	public String toString() {
		return TO_STRING + getURI().toString() + READ_COUNT_TO_STRING + new Integer(readReferenceCount) + WRITE_COUNT_TO_STRING + new Integer(editReferenceCount);
	}

	/*
	 * @see ReferencedResource#needsToSave()
	 */
	@Override
	public boolean needsToSave() {
		return isModified() && !isSharedForWrite();
	}


	/**
	 * @see ReferencedResource#setForceRefresh(boolean)
	 */
	@Override
	public void setForceRefresh(boolean b) {
		forceRefresh = b;
	}

	/**
	 * @see ReferencedResource#shouldForceRefresh()
	 */
	@Override
	public boolean shouldForceRefresh() {
		return forceRefresh;
	}

	@Override
	protected void basicDoLoad(InputStream arg0, Map arg1) throws IOException {
		boolean isTrackingMods = isTrackingModification();
		try {
			if (isTrackingMods)
				setTrackingModification(false);
			super.basicDoLoad(arg0, arg1);
		} finally {
			if (isTrackingMods)
				setTrackingModification(true);
		}
	}

	/**
	 * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#doUnload()
	 */
	@Override
	protected void doUnload() {
		
		try {
			// Using load lock to ensure no other threads will attempt a load during the unload process
			addSynchronizationLoadingAdapter();
			waitForResourceToLoadIfNecessary();
			
			if (isTrackingModification() && editReferenceCount < 1) //do not turn off modification if
				// we still have a write count
				setTrackingModification(false);
			super.doUnload();
			setForceRefresh(false);
			setModified(false); //dcb - this is required to ensure that resources without files are
			// marked as not modified.
			if (readReferenceCount == 0 && editReferenceCount == 0 && getResourceSet() != null) {
				getResourceSet().getResources().remove(this);
			}
		
		} finally {
			//Removing the load lock
			removeLoadingSynchronizationAdapter();
		}
			
	}


	/**
	 * The resource has been unloaded, and there are no references. Treat the resource like a new
	 * Resource
	 */
	// never used
//	private void resetAsNew() {
//		readReferenceCount = 1;
//		isNew = true;
//	}

	/**
	 * @see org.eclipse.emf.ecore.resource.Resource#save(Object)
	 */
	@Override
	public void save(Map options) throws IOException {
		notifyAboutToSave();
        try {
            super.save(options);
        } catch (Exception e) {
            notifySaveFailed();
            if (e instanceof IOException)
                throw (IOException) e;
            EcoreUtilitiesPlugin.logError(e);
        }
        notifySaved();
	}

	protected void notifySaved() {
		notifySaveEvent(RESOURCE_WAS_SAVED);
	}
	
	protected void notifyAboutToSave() {
        notifySaveEvent(RESOURCE_ABOUT_TO_SAVE);
    }
	
	protected void notifySaveFailed() {
        notifySaveEvent(RESOURCE_SAVE_FAILED);
    }
	
	private void notifySaveEvent(int eventType) {
		if (eNotificationRequired()) {
		  Notification notification =
			new NotificationImpl(eventType, this, this)
			{
			  @Override
			public Object getNotifier()
			  {
				return ReferencedXMIResourceImpl.this;
			  }
			  @Override
			public int getFeatureID(Class expectedClass)
			  {
				return eventType;
			  }
			};
			eNotify(notification);
		}
	}	

	/**
	 * @see com.ibm.etools.emf.workbench.ReferencedResource#wasReverted()
	 */
	@Override
	public boolean wasReverted() {
		return false;
	}
	
	@Override
	public EList eAdapters()
	  {
	    if (eAdapters == null)
	    {
	      eAdapters =  new ESynchronizedAdapterList(this);
	    }
	    return eAdapters;
	  }


}
