/**
 *
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.tuscany.sdo.impl;


import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.tuscany.sdo.SDOFactory;
import org.apache.tuscany.sdo.SDOPackage;
import org.apache.tuscany.sdo.util.BasicSequence;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.impl.ChangeDescriptionImpl;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.util.InternalEList;

import commonj.sdo.ChangeSummary;
import commonj.sdo.ChangeSummary.Setting;
import commonj.sdo.DataGraph;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.Sequence;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>EChange Summary</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.apache.tuscany.sdo.impl.ChangeSummaryImpl#getEDataGraph <em>EData Graph</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class ChangeSummaryImpl extends ChangeDescriptionImpl implements ChangeSummary
{
  /**
	 * The cached value of the '{@link #getEDataGraph() <em>EData Graph</em>}' reference.
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @see #getEDataGraph()
	 * @generated
	 * @ordered
	 */
  protected DataGraph eDataGraph;
  
  protected DataObject dataObject = null;
  protected SDOChangeRecorder changeRecorder = null;
  
  protected Set cachedDeletedObjects = null;
  protected List cachedCreatedObjects = null;
  protected Map cachedSDOObjectChanges = null;  
  protected boolean isStale = false;

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 */
  protected ChangeSummaryImpl()
  {
		super();
		cachedSDOObjectChanges = createThreadSafeMap();
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  protected EClass eStaticClass()
  {
		return SDOPackage.Literals.CHANGE_SUMMARY;
	}

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public boolean isLogging()
  {
    return changeRecorder != null;
  }

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public DataGraph getEDataGraph()
  {
		return eDataGraph;
	}
  
  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public NotificationChain basicSetEDataGraph(DataGraph newEDataGraph, NotificationChain msgs)
  {
		DataGraph oldEDataGraph = eDataGraph;
		eDataGraph = newEDataGraph;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH, oldEDataGraph, newEDataGraph);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public void setEDataGraph(DataGraph newEDataGraph)
  {
		if (newEDataGraph != eDataGraph) {
			NotificationChain msgs = null;
			if (eDataGraph != null)
				msgs = ((InternalEObject)eDataGraph).eInverseRemove(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
			if (newEDataGraph != null)
				msgs = ((InternalEObject)newEDataGraph).eInverseAdd(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
			msgs = basicSetEDataGraph(newEDataGraph, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH, newEDataGraph, newEDataGraph));
	}

  public DataObject getDataObject()
  {
    return dataObject;
  }

  public void setDataObject(DataObject newDataObject)
  {
    dataObject = newDataObject;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void beginLogging()
  {
    if (isLogging())
    {
      throw new IllegalStateException("Already logging");
    }

    getObjectsToAttach().clear();
    getObjectChanges().clear();
    getResourceChanges().clear();
    oldContainmentInformation = null;

    beginRecording();
//    if (eNotificationRequired())
//      eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, false, true));
  }
  
  /**
   * 
   */
  private void beginRecording() {
    changeRecorder = new SDOChangeRecorder();
    if (eDataGraph != null) 
    {
      changeRecorder.beginRecording(Collections.singleton(((DataGraphImpl)eDataGraph).getRootResource()));
    }
    else if (dataObject != null)
    {
      changeRecorder.beginRecording(Collections.singleton(dataObject));
    }
    else
    {
      throw new IllegalStateException("ChangeSummary not attached to any data objects");
    }
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void resumeLogging()
  {
    if (isLogging())
    {
      throw new IllegalStateException("Already logging");
    }

    oldContainmentInformation = null;
    
    beginRecording();
//    if (eNotificationRequired())
//      eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, false, true));
  }  

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				return getEDataGraph();
		}
		return super.eGet(featureID, resolve, coreType);
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public void eSet(int featureID, Object newValue)
  {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				setEDataGraph((DataGraph)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public void eUnset(int featureID)
  {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				setEDataGraph((DataGraph)null);
				return;
		}
		super.eUnset(featureID);
	}

  /**
	 * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
	 * @generated
	 */
  public boolean eIsSet(int featureID)
  {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				return eDataGraph != null;
		}
		return super.eIsSet(featureID);
	}

  protected void uncache()
  {
    cachedDeletedObjects = null;
    cachedCreatedObjects = null;
    cachedSDOObjectChanges.clear();
  }

  protected class SDOChangeRecorder extends ChangeRecorder
  {
    public SDOChangeRecorder()
    {
      super();
    }
    
    public void beginRecording(ChangeDescription changeDescription, Collection rootObjects)
    {
      uncache();
      super.beginRecording(changeDescription, rootObjects);
    }

    protected ChangeDescription createChangeDescription()
    {
      return ChangeSummaryImpl.this;
    }

    protected FeatureChange createFeatureChange(EObject eObject, EStructuralFeature eStructuralFeature, Object value, boolean isSet)
    {
      Property property = (Property)eStructuralFeature;
      if (property.isReadOnly())
      {
        if (((DataObject)eObject).getDataGraph() != null)
        {
          throw 
            new IllegalStateException
              ("The property '" + property.getName() + "' of type '" + 
                 property.getContainingType().getName() + "' is read only");
        }
      }
      return (FeatureChange)SDOFactory.eINSTANCE.createChangeSummarySetting(eStructuralFeature, value, isSet);
    }
    
    protected void consolidateChanges()
    {
      uncache();
      isStale = false;
      
      // TODO remove this fixup when https://bugs.eclipse.org/bugs/show_bug.cgi?id=177235 is
      // available to us (i.e. we update to EMF 2.3) -- see Tuscany-1164
      boolean isUncontainedRoot = dataObject != null
        && ((EObject)dataObject).eContainer() == null
        && ((EObject)dataObject).eResource() == null;
      
      super.consolidateChanges();
      
      if(isUncontainedRoot && changeDescription.getObjectsToAttach().contains(dataObject)) {
        changeDescription.getObjectsToAttach().remove(dataObject);
      }
      
    }

    protected void addAdapter(Notifier notifier)
    {
      if (!loadingTargets) return; // Optimize ChangeSummary to not record changes in newly created DOs

      if (notifier instanceof DataObjectImpl)
        ((DataObjectImpl)notifier).setChangeRecorder(this);
      else
        super.addAdapter(notifier);
    }

    protected void removeAdapter(Notifier notifier)
    {
      if (notifier instanceof DataObjectImpl)
        ((DataObjectImpl)notifier).setChangeRecorder(null);
      else
        super.removeAdapter(notifier);
    }
    
    public void notifyChanged(Notification notification) 
    { 
      super.notifyChanged(notification);

      Object notifier = notification.getNotifier();
      if (notifier instanceof EObject)
      {
        cachedSDOObjectChanges.remove(notifier);
        Object feature = notification.getFeature();
        if (feature instanceof Property && ((Property)feature).isContainment())
        {
          cachedCreatedObjects = null;
          cachedDeletedObjects = null;
          oldContainmentInformation = null;
        }
        isStale = true;
      }
    }

  } 

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void endLogging()
  {
    if (!isLogging())
    {
      throw new IllegalStateException("Not currently logging");
    }
    
    changeRecorder.endRecording();
    changeRecorder.dispose();
    changeRecorder = null;
//    if (eNotificationRequired())
//      eNotify(new ENotificationImpl(this, Notification.SET, SDOPackage.ECHANGE_SUMMARY__LOGGING, true, false));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public boolean isCreated(DataObject dataObject)
  {
    return getCachedCreatedObjects().contains(dataObject);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public boolean isDeleted(DataObject dataObject)
  {
    return getCachedDeletedObjects().contains(dataObject);
  }

  protected Set getCachedDeletedObjects()
  {
    if (cachedDeletedObjects == null)
    {
      if (isStale()) changeRecorder.consolidateChanges();
      cachedDeletedObjects = new HashSet();
      for (Iterator i = EcoreUtil.getAllContents(getObjectsToAttach()); i.hasNext(); )
      {
        cachedDeletedObjects.add(i.next());
      }
    }
    return cachedDeletedObjects;
  }

  protected List getCachedCreatedObjects()
  {
    if (cachedCreatedObjects == null)
    {
      if (isStale()) changeRecorder.consolidateChanges();
      cachedCreatedObjects = super.getObjectsToDetach();
    }
    return cachedCreatedObjects;
  }
  
  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public List getChangedDataObjects()
  {
    EList result = new UniqueEList.FastCompare(getCachedDeletedObjects());
    result.addAll(getCachedCreatedObjects());
    for (Iterator i = getObjectChanges().iterator(); i.hasNext(); )
    {
      Map.Entry entry = (Map.Entry)i.next();
      result.add(entry.getKey());
    }
    return result;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public List getOldValues(DataObject dataObject)
  {
    List sdoSettings = (List)cachedSDOObjectChanges.get(dataObject);
    if (sdoSettings != null)
    {
      return sdoSettings;
    }

    if (isStale()) changeRecorder.consolidateChanges();
    List settings = (List)getObjectChanges().get(dataObject);
    if (settings == null)
    {
      settings = Collections.EMPTY_LIST;
    }
    else
    {
      for (int i = 0; i < settings.size(); i++)
      {
        FeatureChange change = (FeatureChange)settings.get(i);
        EStructuralFeature feature = change.getFeature();
        if (FeatureMapUtil.isFeatureMap(feature))
        {
          final List values = (List)change.getValue();
          if (sdoSettings == null)
          {
            sdoSettings = new BasicEList(settings);
          }
          DelegatingFeatureMap featureMap = new DelegatingFeatureMap(((InternalEObject)dataObject), feature)
            {
              protected final List theList = values;
  
              protected List delegateList()
              {
                return theList;
              }
            };
  
          // create new settings and replace the setting for mixed feature
          sdoSettings.set(i, SDOFactory.eINSTANCE.createChangeSummarySetting(feature, new BasicSequence(featureMap), change.isSet()));
          // add all derived features
          for (int k = 0; k < featureMap.size(); k++)
          {
            EStructuralFeature f = featureMap.getEStructuralFeature(k);
            sdoSettings.add(SDOFactory.eINSTANCE.createChangeSummarySetting(f, featureMap.get(f, false), true));
          }
        }
      }
    }
    sdoSettings = (sdoSettings != null) ? sdoSettings : settings;
    cachedSDOObjectChanges.put(dataObject, sdoSettings);
    return sdoSettings;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public boolean isModified(DataObject dataObject)
  {
    return getObjectChanges().containsKey(dataObject) && !isDeleted(dataObject) && !isCreated(dataObject);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void summarize()
  {
    if (!isLogging())
    {
      throw new IllegalStateException("Not currently logging");
    }
    
    changeRecorder.summarize();
  }

  public Setting getOldValue(DataObject dataObject, Property property)
  {
    for (Iterator i = getOldValues(dataObject).iterator(); i.hasNext(); )
    {
      Setting setting = (Setting)i.next();
      if (setting.getProperty() == property)
      {
        return setting;
      }
    }

    return null;
  }

  public DataObject getOldContainer(DataObject dataObject)
  {
    return (DataObject)getOldContainer((EObject)dataObject);
  }

  public Property getOldContainmentProperty(DataObject dataObject)
  {
    return (Property)getOldContainmentFeature((EObject)dataObject);
  }
  
  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Sequence getOldSequence(DataObject dataObject)
  {
    EAttribute mixedFeature = BasicExtendedMetaData.INSTANCE.getMixedFeature((EClass)dataObject.getType());
    if (mixedFeature != null)
    {
      return (Sequence)getOldValue(dataObject, (Property)mixedFeature).getValue();
    }
    return null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void undoChanges()
  {
    if (isLogging())
    {
      changeRecorder.summarize();
    }
    else
    {
      uncache();
    }
    apply();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public DataGraph getDataGraph()
  {
    return getEDataGraph();
  }
  
  /**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List getChangedObjects() {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

		protected Map getOldContainmentInformation()
  {
    if (oldContainmentInformation == null)
    {
      if (isStale()) changeRecorder.consolidateChanges();
      super.getOldContainmentInformation();
    }
    return oldContainmentInformation;
  }

  protected boolean isStale()
  {
    return isLogging() && isStale;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public DataObject getRootObject()
  {
    if (eDataGraph != null)
    {
      return eDataGraph.getRootObject();
    }
    if (dataObject != null)
    {
      return dataObject;
    }
    return null;
  }

  /**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				if (eDataGraph != null)
					msgs = ((InternalEObject)eDataGraph).eInverseRemove(this, SDOPackage.DATA_GRAPH__ECHANGE_SUMMARY, DataGraph.class, msgs);
				return basicSetEDataGraph((DataGraph)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

		/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case SDOPackage.CHANGE_SUMMARY__EDATA_GRAPH:
				return basicSetEDataGraph(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

		static protected boolean isContainmentReference(Object feature)
  {
    return feature instanceof EReference && ((EReference) feature).isContainment();
  }  
  
  public DataObject getOldDataObject(DataObject dataObject)
  {
    //TODO: Fix this method. Currently, it has the side effect of undoing the unset of contained children references
    //      of root deleted objects - i.e., when featureChange.apply(oldDataObject) is called.
    //
    List changes = (List) getObjectChanges().get(dataObject);
    if (changes == null) 
      return dataObject;
    EObject oldDataObject = EcoreUtil.copy((EObject)dataObject);
    for (Iterator fIter = changes.iterator(); fIter.hasNext(); )
    {
      FeatureChange featureChange = (FeatureChange)fIter.next();
      featureChange.apply(oldDataObject);
      EStructuralFeature feature = featureChange.getFeature();
      if (FeatureMapUtil.isFeatureMap(feature))
      {
        FeatureMap featureMap = (FeatureMap) oldDataObject.eGet(feature);
        for (int index = featureMap.size(); index != 0;)
          if (isContainmentReference(featureMap.getEStructuralFeature(--index)))
            featureMap.setValue(index, getOldDataObject((DataObject) featureMap.getValue(index)));
      }
      else if (isContainmentReference(feature))
      {
        Object value = oldDataObject.eGet(feature);
        if (feature.isMany())
        {
          changes = (List) value;
          for (int index = changes.size(); index != 0;)
            changes.set(--index, getOldDataObject((DataObject) changes.get(index))); // Java pushes stack from left to right
        }
        else
          oldDataObject.eSet(feature, getOldDataObject((DataObject) value));
      }
    }

    return (DataObject)oldDataObject;
  }
  
  private static Class concurrentHashMapClazz = null;
  private static boolean isThreadSafeMapClazzIdentified = false;

  private Map createThreadSafeMap() 
  {
    if (!isThreadSafeMapClazzIdentified) 
    {
      concurrentHashMapClazz = loadConcurrentHashMapClazz();
      isThreadSafeMapClazzIdentified = true;
    }
    Map threadSafeMap = null;
    if (concurrentHashMapClazz == null) 
    {
      threadSafeMap = Collections.synchronizedMap(new HashMap());
    } 
    else 
    {
      try 
      {
        threadSafeMap = (Map)concurrentHashMapClazz.newInstance();
      } 
      catch (InstantiationException e) 
      {
        throw new RuntimeException(e);
      } 
      catch (IllegalAccessException e) 
      {
        throw new RuntimeException(e);
      }
    }
    return threadSafeMap;
  }

  private static String[] concurrentHashMapClazzNames = new String[] {
      "java.util.concurrent.ConcurrentHashMap", 
      "edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap"};

  private static Class loadConcurrentHashMapClazz() 
  {
    Class mapClazz = null;
    for (int i = 0; i < concurrentHashMapClazzNames.length; i++) 
    {
      String concurrentHashMapClazzName = concurrentHashMapClazzNames[i];
      try 
      {
        mapClazz = Class.forName(concurrentHashMapClazzName, true, Thread.currentThread().getContextClassLoader());
      } 
      catch (Exception ignored) {}
      if (mapClazz != null) 
      {
        break;
      }
      try 
      {
        mapClazz = Class.forName(concurrentHashMapClazzName);
      } 
      catch (Exception ignored) {}
      if (mapClazz != null) 
      {
        break;
      }
    }
    return mapClazz;
  }
  
} //ChangeSummaryImpl
