/*
 * Copyright (c) 2008-2013, 2015, 2016 Eike Stepper (Loehne, Germany) 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:
 *    Martin Taal - initial API and implementation
 *    Eike Stepper - maintenance
 */
package org.eclipse.emf.cdo.server.internal.hibernate;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.id.CDOIDString;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.hibernate.IHibernateMappingProvider;
import org.eclipse.emf.cdo.server.hibernate.IHibernateStore;
import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;

import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.proxy.HibernateProxy;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * Provides several utility and convenience methods. Mostly related to {@link CDOID} and {@link CDORevision}.
 *
 * @author Martin Taal
 */
public class HibernateUtil
{
  private static final String EXT_POINT = "mappingProviderFactories"; //$NON-NLS-1$

  private static HibernateUtil instance = new HibernateUtil();

  private static final String SEPARATOR = "_;_"; //$NON-NLS-1$

  private static final String MAPPING_PROVIDER_FACTORY_TAG = "mappingProviderFactory"; //$NON-NLS-1$

  private static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$

  private static final String CLASS = "class"; //$NON-NLS-1$

  private static IHibernateMappingProvider.Factory mappingProviderFactoryInstance = null;

  public static IHibernateMappingProvider.Factory getMappingProviderFactoryInstance()
  {
    return mappingProviderFactoryInstance;
  }

  public static void setMappingProviderFactoryInstance(IHibernateMappingProvider.Factory theMappingProviderFactoryInstance)
  {
    mappingProviderFactoryInstance = theMappingProviderFactoryInstance;
  }

  /**
   * @return the global singleton instance
   */
  public static HibernateUtil getInstance()
  {
    return instance;
  }

  /**
   * Sets the singleton used by the Hibernate store.
   *
   * @param instance
   *          the instance to set
   */
  public static void setInstance(HibernateUtil instance)
  {
    HibernateUtil.instance = instance;
  }

  // Local copy of the datatype factory
  private DatatypeFactory dataTypeFactory;

  public HibernateUtil()
  {
    try
    {
      dataTypeFactory = DatatypeFactory.newInstance();
    }
    catch (DatatypeConfigurationException ex)
    {
      throw new IllegalStateException("Exception ", ex);
    }
  }

  public DatatypeFactory getDataTypeFactory()
  {
    return dataTypeFactory;
  }

  public void setDataTypeFactory(DatatypeFactory dataTypeFactory)
  {
    this.dataTypeFactory = dataTypeFactory;
  }

  /**
   * @return true if the efeature is {@link CDOResource#getContents()} efeature.
   */
  public boolean isCDOResourceContents(EStructuralFeature eFeature)
  {
    if (!eFeature.getEContainingClass().getEPackage().getNsURI().equals(EresourcePackage.eNS_URI))
    {
      return false;
    }
    if (!eFeature.getEContainingClass().getName().equals(EresourcePackage.eINSTANCE.getCDOResource().getName()))
    {
      return false;
    }
    if (!eFeature.getName().equals(EresourcePackage.eINSTANCE.getCDOResource_Contents().getName()))
    {
      return false;
    }
    return true;
  }

  /**
   * Uses the repository package repository to find the EClass of the identified by the CDOClassifierRef.
   *
   * @param classifierRef
   *          {@link CDOClassifierRef} which identifies an EClass
   * @return the EClass instance identified by the EPackage nsuri and classifier name in the CDOClassifierRef
   * @throws IllegalArgumentException
   *           if the EClass can not be found
   * @see IRepository#getPackageRegistry()
   */
  public EClass getEClass(CDOClassifierRef classifierRef)
  {
    final CDOPackageRegistry registry = getPackageRegistry();
    final EPackage ePackage = registry.getEPackage(classifierRef.getPackageURI());
    if (ePackage == null)
    {
      throw new IllegalArgumentException("No EPackage found with nsuri " + classifierRef.getPackageURI()); //$NON-NLS-1$
    }

    final EClass eClass = (EClass)ePackage.getEClassifier(classifierRef.getClassifierName());
    if (eClass == null)
    {
      throw new IllegalArgumentException("No EClass " + classifierRef.getClassifierName() + " in EPackage " //$NON-NLS-1$ //$NON-NLS-2$
          + ePackage.getNsURI());
    }

    return eClass;
  }

  /**
   * @return the package registry as present in the repository
   * @see HibernateStore#getRepository()
   * @see IRepository#getPackageRegistry()
   */
  public CDOPackageRegistry getPackageRegistry()
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getStore().getRepository().getPackageRegistry();
  }

  /**
   * Creates an instance of {@link IHibernateStore}.
   *
   * @param mappingProvider
   *          the provider which generates a mapping.
   * @param properties
   *          hibernate and teneo properties combined
   * @return the created HibernateStore
   * @see HibernateStore
   * @since 2.0
   */
  public IHibernateStore createStore(IHibernateMappingProvider mappingProvider, Properties properties)
  {
    HibernateStore store = new HibernateStore(mappingProvider, properties);
    mappingProvider.setHibernateStore(store);
    return store;
  }

  /**
   * Can only be used when Eclipse is running. In standalone scenarios create the mapping strategy instance by directly
   * calling the constructor of the mapping strategy class.
   *
   * @see #createFileMappingProvider(String)
   * @since 2.0
   */
  public IHibernateMappingProvider.Factory createMappingProviderFactory(String type)
  {
    IExtensionRegistry registry = Platform.getExtensionRegistry();
    if (registry == null)
    {
      return getMappingProviderFactoryInstance();
    }
    IConfigurationElement[] elements = registry.getConfigurationElementsFor(OM.BUNDLE_ID, EXT_POINT);
    for (final IConfigurationElement element : elements)
    {
      if (MAPPING_PROVIDER_FACTORY_TAG.equals(element.getName()))
      {
        String typeAttr = element.getAttribute(TYPE_ATTRIBUTE);
        if (ObjectUtil.equals(typeAttr, type))
        {
          try
          {
            return (IHibernateMappingProvider.Factory)element.createExecutableExtension(CLASS);
          }
          catch (CoreException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
      }
    }

    return getMappingProviderFactoryInstance();
  }

  /**
   * Creates a FileMappingProvider using the passed locations.
   *
   * @param location
   *          the locations to load the mappings from
   * @return a {@link FileHibernateMappingProvider}
   * @since 3.0
   */
  public IHibernateMappingProvider createFileMappingProvider(String location)
  {
    return new FileHibernateMappingProvider(location);
  }

  /**
   * Retrieves the Hibernate Session from the current {@link HibernateStoreAccessor}. The current HibernateStoreAccessor
   * is maintained in the {@link HibernateThreadContext}.
   *
   * @return the current hibernate session, if none is there a new one is created and a transaction is started.
   * @since 2.0
   */
  public Session getHibernateSession()
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getHibernateSession();
  }

  /**
   * Convenience method to convert the properties of the {@link IStore#getRepository()} to a real java Properties
   * object.
   *
   * @param store
   *          the properties of this store are converted to a real Properties object
   * @return a Properties object with the store properties
   */
  public Properties getPropertiesFromStore(IHibernateStore store)
  {
    final Properties props = new Properties();

    final Map<String, String> storeProps = store.getRepository().getProperties();
    for (String key : storeProps.keySet())
    {
      props.setProperty(key, storeProps.get(key));
    }

    return props;
  }

  /**
   * Checks if the object is a HibernateProxy. If so creates the CDOID without resolving the hibernate proxy. If it not
   * a proxy then the id is retrieved from the object itself. It is assumed to be a CDORevision then.
   */
  public CDOID getCDOID(Object o)
  {
    if (o instanceof HibernateProxy)
    {
      final Object idValue = ((HibernateProxy)o).getHibernateLazyInitializer().getIdentifier();
      final String entityName = ((HibernateProxy)o).getHibernateLazyInitializer().getEntityName();
      final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
      EClass eClass = accessor.getStore().getEClass(entityName);
      if (eClass.isInterface() || eClass.isAbstract())
      {
        // load the object to get the real eClass
        // cdo can't handle cdoids with the interface/abstract references
        // need the concrete implementation
        ((HibernateProxy)o).getHibernateLazyInitializer().initialize();
        final CDORevision loadedRevision = (CDORevision)((HibernateProxy)o).getHibernateLazyInitializer()
            .getImplementation((SessionImplementor)accessor.getHibernateSession());
        return loadedRevision.getID();
      }

      return HibernateUtil.getInstance().createCDOID(new CDOClassifierRef(eClass), idValue);
    }

    return ((CDORevision)o).getID();
  }

  /**
   * Reads the entity name while taking account the fact that the object maybe a Hibernate proxy.
   */
  public String getEntityName(Object o)
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    if (o instanceof HibernateProxy)
    {
      final String entityName = ((HibernateProxy)o).getHibernateLazyInitializer().getEntityName();
      final EClass eClass = accessor.getStore().getEClass(entityName);
      if (eClass.isInterface() || eClass.isAbstract())
      {
        // load the object to get the real eClass
        // cdo can't handle cdoids with the interface/abstract references
        // need the concrete implementation
        ((HibernateProxy)o).getHibernateLazyInitializer().initialize();
        final CDORevision loadedRevision = (CDORevision)((HibernateProxy)o).getHibernateLazyInitializer()
            .getImplementation((SessionImplementor)accessor.getHibernateSession());
        return accessor.getStore().getEntityName(loadedRevision.getEClass());
      }
      return entityName;
    }

    final EClass eClass = ((CDORevision)o).getEClass();
    return accessor.getStore().getEntityName(eClass);
  }

  /**
   * Deprecated method use: {@link HibernateStore#getEntityName(EClass)}.
   */
  @Deprecated
  public String getEntityName(CDORevision revision)
  {
    return getEntityName((Object)revision);
  }

  /**
   * Converts a CDOID to an unique String representations. Null, {@link CDOIDTemp} and null CDOID's are returned as null
   * value. Supports {@link CDOID} and {@link CDOIDExternal}.
   *
   * @param id
   *          the id to convert
   * @return a unique String
   */
  public String convertCDOIDToString(CDOID id)
  {
    if (id == null || id.isNull() || id.isTemporary())
    {
      return null;
    }

    final StringBuilder sb = new StringBuilder();
    CDOIDUtil.write(sb, id);
    return sb.toString();
  }

  /**
   * Converts a String back to its CDOID representation. The same types as in the {@link #convertCDOIDToString(CDOID)}
   * method are supported.
   *
   * @param strID
   *          the String representation of the CDOID
   * @return a valid CDOID, can be null
   */
  public CDOID convertStringToCDOID(String strID)
  {
    if (strID == null)
    {
      return null;
    }

    return CDOIDUtil.read(strID);
  }

  /**
   * Translates a temporary {@link CDOID} into a hibernate ID, by finding the object it refers to in the
   * {@link CommitContext} and then returning or by persisting the object. Note assumes that the hibernate session and
   * CommitContext are set in HibernateThreadContext.
   *
   * @param id
   *          the CDOID to translate to a valid id, if the id is already valid then it is returned.
   * @return the passed id or an instance of CDOID which is valid.
   */
  public CDOID getCDOIDHibernate(CDOID id)
  {
    if (isStoreCreatedID(id))
    {
      return id;
    }

    final CDORevision revision = getCDORevision(id);
    if (isStoreCreatedID(revision.getID()))
    {
      return revision.getID();
    }

    return getCDOIDHibernate(revision);
  }

  /**
   * Retrieves a {@link CDOID} from the passed CDORevision. If the revision has a non-supported CDOID then the revision
   * is saved to the database.
   *
   * @param revision
   *          the revision to get the id from
   * @return a CDOID supported by this store
   */
  public CDOID getCDOIDHibernate(final CDORevision revision)
  {
    final Session session = getHibernateSession();
    if (!isStoreCreatedID(revision.getID()))
    {
      session.saveOrUpdate(revision);
    }

    checkIsSupportedID(revision.getID());

    return revision.getID();
  }

  /**
   * Retrieves the {@link InternalCDORevision} if the target is a {@link CDOObject} then the CDORevision is retrieved
   * using: {@link CDOObject#cdoRevision()}.
   *
   * @param target
   *          the object which can be a CDOObject or an InternalCDORevision
   * @return the found {@link InternalCDORevision}
   */
  public InternalCDORevision getCDORevision(Object target)
  {
    if (target instanceof CDOObject)
    {
      return (InternalCDORevision)CDOUtil.getCDOObject((EObject)target).cdoRevision();
    }
    return (InternalCDORevision)target;
  }

  /**
   * Gets a current object, first checks the new and dirty objects from the {@link CommitContext}. Otherwise reads it
   * from the session.
   *
   * @param id
   *          the {@link CDOID}, the {@link CDOIDTemp} is resolved against the CommitContext.
   * @return the retrieved {@link CDORevision} or null if the id is a null ({@link CDOIDUtil#isNull(CDOID)})
   */
  public InternalCDORevision getCDORevision(CDOID id)
  {
    if (CDOIDUtil.isNull(id))
    {
      return null;
    }

    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();
      InternalCDORevision revision;
      // if ((revision = commitContext.getDirtyObject(id)) != null)
      // {
      // return revision;
      // }

      if ((revision = commitContext.getNewObject(id)) != null)
      {
        return revision;
      }

      // maybe the temp was already translated
      final CDOID newID = commitContext.getCommitContext().getIDMappings().get(id);
      if (newID != null)
      {
        return getCDORevision(newID);
      }
    }

    checkIsSupportedID(id);

    final String entityName = getEntityName(id);
    final Serializable idValue = getIdValue(id);
    return (InternalCDORevision)getHibernateSession().get(entityName, idValue);
  }

  /**
   * Retrieves a {@link InternalCDORevision} from the {@link CommitContext} or from the database/hibernate session.
   * Resolves temporary id's: {@link CDOIDTemp}.
   *
   * @param id
   *          the {@link CDOID} identifying the object,
   * @return the retrieved CDORevision or null if the revision is not found
   */
  public InternalCDORevision getCDORevisionNullable(CDOID id)
  {
    if (CDOIDUtil.isNull(id))
    {
      return null;
    }

    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();
      InternalCDORevision revision;
      if ((revision = commitContext.getDirtyObject(id)) != null)
      {
        return revision;
      }

      if ((revision = commitContext.getNewObject(id)) != null)
      {
        return revision;
      }

      // maybe the temp was already translated
      if (id instanceof CDOIDTemp)
      {
        final CDOID newID = commitContext.getCommitContext().getIDMappings().get(id);
        if (newID != null)
        {
          return getCDORevision(newID);
        }
      }
    }

    if (!isStoreCreatedID(id))
    {
      return null;
    }

    final String entityName = getEntityName(id);
    final Serializable idValue = getIdValue(id);
    return (InternalCDORevision)getHibernateSession().get(entityName, idValue);
  }

  /**
   * Converts a String to a containing feature id. Note this is not the same as the feature id. The feature is the
   * containing feature of the passed EObject.
   *
   * @param contained
   *          the object which is contained
   * @param value
   *          the value to convert
   * @return the containing feature id.
   * @see #getContainerFeatureId(EClass, EObject, EStructuralFeature)
   */
  public int convertStringToFeatureID(EObject contained, String value)
  {
    final String[] values = value.split(SEPARATOR);
    final String nsuri = values[0];
    final EPackage eContainerPackage = getPackageRegistry().getEPackage(nsuri);
    final String eContainerEClassName = values[1];
    final EClass eContainingClass = (EClass)eContainerPackage.getEClassifier(eContainerEClassName);

    final EPackage eFeaturePackage = getPackageRegistry().getEPackage(values[2]);

    final String eClassifierName = values[3];
    final EClassifier eClassifier = eFeaturePackage.getEClassifier(eClassifierName);
    final EClass eFeatureClass = (EClass)eClassifier;
    final String eFeatureName = values[4];
    final EStructuralFeature eFeature = eFeatureClass.getEStructuralFeature(eFeatureName);
    return getContainerFeatureId(eContainingClass, contained, eFeature);
  }

  /**
   * Computes a valid containing feature id for a passed containing EClass, the contained object and the
   * EStructuralFeature which can be the container or the containment feature.
   *
   * @param containingEClass
   *          the EClass representing the container
   * @param contained
   *          the EObject which is contained
   * @param eFeature
   *          the EStructuralFeature, can be the efeature of the containingEClass or of the contained.
   */
  public int getContainerFeatureId(EClass containingEClass, EObject contained, EStructuralFeature eFeature)
  {
    if (eFeature instanceof EAttribute)
    {
      // featuremap??
      return InternalEObject.EOPPOSITE_FEATURE_BASE - containingEClass.getFeatureID(eFeature);
    }

    final EReference eReference = (EReference)eFeature;
    if (eReference.getEOpposite() != null)
    {
      final EReference containerEReference = eReference.getEOpposite();
      return contained.eClass().getFeatureID(containerEReference);
    }
    return InternalEObject.EOPPOSITE_FEATURE_BASE - containingEClass.getFeatureID(eReference);
  }

  /**
   * Creates the correct subclass of {@link CDOID} for the passed EClass and hibernate id object.
   *
   * @param classifierRef
   *          the EClass to set in the CDOID
   * @param idValue
   *          the real id value
   * @return a supported instance of CDOID.
   * @see CDOIDUtil
   */
  public CDOID createCDOID(CDOClassifierRef classifierRef, Object idValue)
  {
    if (idValue instanceof String)
    {
      return CDOIDUtil.createStringWithClassifier((String)idValue, classifierRef);
    }

    if (idValue instanceof Long)
    {
      return CDOIDUtil.createLongWithClassifier((Long)idValue, classifierRef);
    }

    throw new IllegalArgumentException("The ID value type " + idValue.getClass() //$NON-NLS-1$
        + " is not supported by this store. Method called with " + classifierRef); //$NON-NLS-1$
  }

  /**
   * Checks if the passed id is created/used by this store.
   *
   * @param id
   *          the {@link CDOID} to check
   * @return true if this is a CDOID which is used/created by this store.
   */
  public boolean isStoreCreatedID(CDOID id)
  {
    // TODO: not the nicest check but we know that only these are supported
    // by the hibernatestore
    return id instanceof CDOClassifierRef.Provider || id instanceof CDOIDExternal;
  }

  /**
   * Checks if the passed {@link CDOID} is a type supported by this store.
   *
   * @param id
   *          the CDOID instance to check
   * @throws IllegalArgumentException
   *           if the passed type is not supported.
   */
  public void checkIsSupportedID(CDOID id)
  {
    if (!isStoreCreatedID(id))
    {
      throw new IllegalArgumentException("This CDOID type " + id + " is not supported by this store. " //$NON-NLS-1$ //$NON-NLS-2$
          + id.getClass().getName());
    }
  }

  /**
   * @param id
   *          CDOID to get the internal id from
   * @return the id used by Hibernate, the String or Long value in the CDOID object.
   */
  public Serializable getIdValue(CDOID id)
  {
    if (id instanceof CDOIDString)
    {
      return ((CDOIDString)id).getStringValue();
    }
    return CDOIDUtil.getLong(id);
  }

  /**
   * Retrieves the entity name for the EClass present in the CDOID.
   *
   * @param id
   *          the {@link CDOID} to get the EClass from
   * @return the entity name for the EClass of the CDOID.
   * @see HibernateStore#getEntityName(EClass)
   */
  public String getEntityName(CDOID id)
  {
    final CDOID localId = resolvePossibleTempId(id);
    final CDOClassifierRef classifierRef = CDOIDUtil.getClassifierRef(localId);
    if (classifierRef == null)
    {
      throw new IllegalArgumentException("This CDOID type of " + id + " is not supported by this store."); //$NON-NLS-1$ //$NON-NLS-2$
    }

    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getStore().getEntityName(classifierRef);
  }

  /**
   * If the passed in id is a temp id, resolve it against the {@link HibernateThreadContext#getCommitContext()}
   */
  public CDOID resolvePossibleTempId(CDOID cdoId)
  {
    if (!(cdoId instanceof CDOIDTemp))
    {
      return cdoId;
    }
    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();

      final CDOID newID = commitContext.getCommitContext().getIDMappings().get(cdoId);
      if (newID != null)
      {
        return newID;
      }

      InternalCDORevision revision;
      if ((revision = commitContext.getNewObject(cdoId)) != null)
      {
        return revision.getID();
      }
    }
    return cdoId;
  }

  /**
   * Create a {@link XMLGregorianCalendar} from a {@link Date} instance.
   */
  public XMLGregorianCalendar getXMLGregorianCalendarDate(Date date, boolean dateTime)
  {
    final XMLGregorianCalendar gregCalendar = dataTypeFactory.newXMLGregorianCalendar();
    final Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);

    gregCalendar.setYear(calendar.get(Calendar.YEAR));
    gregCalendar.setMonth(calendar.get(Calendar.MONTH) + 1); // correct with 1 on purpose
    gregCalendar.setDay(calendar.get(Calendar.DAY_OF_MONTH));

    if (dateTime)
    {
      gregCalendar.setHour(calendar.get(Calendar.HOUR_OF_DAY));
      gregCalendar.setMinute(calendar.get(Calendar.MINUTE));
      gregCalendar.setSecond(calendar.get(Calendar.SECOND));
      gregCalendar.setMillisecond(calendar.get(Calendar.MILLISECOND));
    }

    return gregCalendar;
  }

}
