/*
 * Copyright (c) 2008-2014, 2016, 2018-2020 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:
 *    Eike Stepper - initial API and implementation
 *    Stefan Winkler - Bug 332912 - Caching subtype-relationships in the CDOPackageRegistry
 *    Erdal Karaca - added support for HASHMAP CDO Type
 *    Christian W. Damus (CEA) - don't validate cross-references in EAnnotations
 */
package org.eclipse.emf.cdo.common.model;

import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
import org.eclipse.emf.cdo.internal.common.model.CDOClassInfoImpl;
import org.eclipse.emf.cdo.internal.common.model.CDOPackageInfoImpl;
import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
import org.eclipse.emf.cdo.internal.common.model.CDOPackageUnitImpl;
import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;

import org.eclipse.net4j.util.io.ExtendedDataInput;
import org.eclipse.net4j.util.io.ExtendedDataOutput;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMapUtil;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Various static helper methods for dealing with CDO meta models.
 *
 * @author Eike Stepper
 * @since 2.0
 */
public final class CDOModelUtil implements CDOModelConstants
{
  private static final EClass ROOT_TYPE = EcorePackage.eINSTANCE.getEObject();

  private static CDOType[] coreTypes;

  static
  {
    List<CDOType> types = new ArrayList<>();
    registerCoreType(types, EcorePackage.eINSTANCE.getEBigDecimal(), CDOType.BIG_DECIMAL);
    registerCoreType(types, EcorePackage.eINSTANCE.getEBigInteger(), CDOType.BIG_INTEGER);
    registerCoreType(types, EcorePackage.eINSTANCE.getEBooleanObject(), CDOType.BOOLEAN_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEBoolean(), CDOType.BOOLEAN);
    registerCoreType(types, EcorePackage.eINSTANCE.getEByteArray(), CDOType.BYTE_ARRAY);
    registerCoreType(types, EcorePackage.eINSTANCE.getEByteObject(), CDOType.BYTE_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEByte(), CDOType.BYTE);
    registerCoreType(types, EcorePackage.eINSTANCE.getECharacterObject(), CDOType.CHARACTER_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEChar(), CDOType.CHAR);
    registerCoreType(types, EcorePackage.eINSTANCE.getEDate(), CDOType.DATE);
    registerCoreType(types, EcorePackage.eINSTANCE.getEDoubleObject(), CDOType.DOUBLE_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEDouble(), CDOType.DOUBLE);
    registerCoreType(types, EcorePackage.eINSTANCE.getEFloatObject(), CDOType.FLOAT_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEFloat(), CDOType.FLOAT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEIntegerObject(), CDOType.INTEGER_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEInt(), CDOType.INT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEJavaClass(), CDOType.JAVA_CLASS);
    registerCoreType(types, EcorePackage.eINSTANCE.getEJavaObject(), CDOType.JAVA_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getELongObject(), CDOType.LONG_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getELong(), CDOType.LONG);
    registerCoreType(types, EcorePackage.eINSTANCE.getEShortObject(), CDOType.SHORT_OBJECT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEShort(), CDOType.SHORT);
    registerCoreType(types, EcorePackage.eINSTANCE.getEString(), CDOType.STRING);
    coreTypes = types.toArray(new CDOType[types.size()]);
  }

  private static void registerCoreType(List<CDOType> types, EClassifier classifier, CDOType type)
  {
    int index = classifier.getClassifierID();
    while (index >= types.size())
    {
      types.add(null);
    }

    types.set(index, type);
  }

  private CDOModelUtil()
  {
  }

  /**
   * @since 2.0
   */
  public static boolean isCorePackage(EPackage ePackage)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[0] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[0] == ePackage;
    }

    String nsURI = ePackage.getNsURI();
    return CORE_PACKAGE_URI.equals(nsURI);
  }

  /**
   * @since 2.0
   */
  public static boolean isRoot(EClass eClass)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[1] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[1] == eClass;
    }

    if (isCorePackage(eClass.getEPackage()))
    {
      String name = eClass.getName();
      return ROOT_CLASS_NAME.equals(name);
    }

    return false;
  }

  /**
   * @since 2.0
   */
  public static boolean isResourcePackage(EPackage ePackage)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[2] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[2] == ePackage;
    }

    String nsURI = ePackage.getNsURI();
    return RESOURCE_PACKAGE_URI.equals(nsURI);
  }

  /**
   * @since 2.0
   */
  public static boolean isResource(EClass eClass)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[3] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[3] == eClass;
    }

    if (isResourcePackage(eClass.getEPackage()))
    {
      String name = eClass.getName();
      return RESOURCE_CLASS_NAME.equals(name);
    }

    return false;
  }

  /**
   * @since 2.0
   */
  public static boolean isResourceFolder(EClass eClass)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[4] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[4] == eClass;
    }

    if (isResourcePackage(eClass.getEPackage()))
    {
      String name = eClass.getName();
      return RESOURCE_FOLDER_CLASS_NAME.equals(name);
    }

    return false;
  }

  /**
   * @since 2.0
   */
  public static boolean isResourceNode(EClass eClass)
  {
    return isResourcePackage(eClass.getEPackage());
  }

  /**
   * @since 4.3
   */
  public static boolean isResourcePathFeature(EStructuralFeature eStructuralFeature)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[8] == eStructuralFeature)
    {
      return true;
    }

    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[9] == eStructuralFeature)
    {
      return true;
    }

    if (isResourceNode(eStructuralFeature.eClass()))
    {
      String name = eStructuralFeature.getName();
      if (RESOURCE_NODE_FOLDER_REFERENCE.equals(name) || RESOURCE_NODE_NAME_ATTRIBUTE.equals(name))
      {
        return true;
      }
    }

    return false;
  }

  /**
   * @since 4.0
   */
  public static boolean isTypesPackage(EPackage ePackage)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[5] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[5] == ePackage;
    }

    String nsURI = ePackage.getNsURI();
    return TYPES_PACKAGE_URI.equals(nsURI);
  }

  /**
   * @since 2.0
   */
  public static boolean isSystemPackage(EPackage ePackage)
  {
    return isCorePackage(ePackage) || isResourcePackage(ePackage) || isTypesPackage(ePackage);
  }

  /**
   * @since 4.7
   */
  public static boolean isSystemPackageURI(String nsURI)
  {
    return CORE_PACKAGE_URI.equals(nsURI) || RESOURCE_PACKAGE_URI.equals(nsURI) || TYPES_PACKAGE_URI.equals(nsURI);
  }

  /**
   * @since 4.0
   */
  public static boolean isLob(EClassifier eClassifier)
  {
    if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[6] != null && CDOPackageRegistryImpl.SYSTEM_ELEMENTS[7] != null)
    {
      return CDOPackageRegistryImpl.SYSTEM_ELEMENTS[6] == eClassifier || CDOPackageRegistryImpl.SYSTEM_ELEMENTS[7] == eClassifier;
    }

    if (isTypesPackage(eClassifier.getEPackage()))
    {
      String name = eClassifier.getName();
      return BLOB_CLASS_NAME.equals(name) || CLOB_CLASS_NAME.equals(name);
    }

    return false;
  }

  /**
   * @since 2.0
   */
  public static CDOType getType(EStructuralFeature feature)
  {
    return getType(feature.getEType());
  }

  /**
   * @since 4.0
   */
  public static CDOType getType(byte typeID)
  {
    return CDOTypeImpl.getType(typeID);
  }

  /**
   * @since 2.0
   */
  public static CDOType getType(EClassifier classifier)
  {
    if (classifier instanceof EClass)
    {
      return CDOType.OBJECT;
    }

    if (classifier instanceof EEnum)
    {
      return CDOType.ENUM_ORDINAL;
    }

    EDataType eDataType = (EDataType)classifier;
    EPackage ePackage = eDataType.getEPackage();

    if (isCorePackage(ePackage))
    {
      CDOType type = getCoreType(eDataType);
      if (type != null)
      {
        return type;
      }
    }
    else if (isTypesPackage(ePackage))
    {
      String name = eDataType.getName();
      if (BLOB_CLASS_NAME.equals(name))
      {
        return CDOType.BLOB;
      }

      if (CLOB_CLASS_NAME.equals(name))
      {
        return CDOType.CLOB;
      }
    }

    return CDOType.CUSTOM;
  }

  /**
   * Core types includes also complex data like EAnnotation, and EEnum
   *
   * @since 2.0
   */
  public static CDOType getCoreType(EClassifier eDataType)
  {
    int index = eDataType.getClassifierID();
    if (0 <= index && index < coreTypes.length)
    {
      return coreTypes[index];
    }

    return null;
  }

  /**
   * @since 2.0
   */
  public static CDOType getPrimitiveType(Class<? extends Object> primitiveType)
  {
    if (primitiveType == String.class)
    {
      return CDOType.STRING;
    }

    if (primitiveType == Boolean.class)
    {
      return CDOType.BOOLEAN;
    }

    if (primitiveType == Integer.class)
    {
      return CDOType.INT;
    }

    if (primitiveType == Double.class)
    {
      return CDOType.DOUBLE;
    }

    if (primitiveType == Float.class)
    {
      return CDOType.FLOAT;
    }

    if (primitiveType == Long.class)
    {
      return CDOType.LONG;
    }

    if (primitiveType == Date.class)
    {
      return CDOType.DATE;
    }

    if (primitiveType == Byte.class)
    {
      return CDOType.BYTE;
    }

    if (primitiveType == Character.class)
    {
      return CDOType.CHAR;
    }

    if (primitiveType == Object[].class)
    {
      return CDOType.OBJECT_ARRAY;
    }

    if (EEnumLiteral.class.isAssignableFrom(primitiveType) || Enumerator.class.isAssignableFrom(primitiveType))
    {
      return CDOType.ENUM_LITERAL;
    }

    if (Map.class.isAssignableFrom(primitiveType))
    {
      return CDOType.MAP;
    }

    if (Set.class.isAssignableFrom(primitiveType))
    {
      return CDOType.SET;
    }

    if (List.class.isAssignableFrom(primitiveType))
    {
      return CDOType.LIST;
    }

    throw new IllegalArgumentException(MessageFormat.format(Messages.getString("CDOModelUtil.7"), primitiveType)); //$NON-NLS-1$
  }

  /**
   * @since 4.0
   */
  public static CDOType getTypeOfObject(Object object)
  {
    if (object == null || object instanceof CDOID || object instanceof CDORevision)
    {
      return CDOType.OBJECT;
    }

    Class<? extends Object> objectClass = object.getClass();
    if (objectClass == String.class)
    {
      return CDOType.STRING;
    }

    if (objectClass == Integer.class)
    {
      return CDOType.INTEGER_OBJECT;
    }

    if (objectClass == Long.class)
    {
      return CDOType.LONG_OBJECT;
    }

    if (objectClass == Boolean.class)
    {
      return CDOType.BOOLEAN_OBJECT;
    }

    if (objectClass == Character.class)
    {
      return CDOType.CHARACTER_OBJECT;
    }

    if (objectClass == Double.class)
    {
      return CDOType.DOUBLE_OBJECT;
    }

    if (objectClass == Float.class)
    {
      return CDOType.FLOAT_OBJECT;
    }

    if (objectClass == Short.class)
    {
      return CDOType.SHORT_OBJECT;
    }

    if (objectClass == Byte.class)
    {
      return CDOType.BYTE_OBJECT;
    }

    if (objectClass == byte[].class)
    {
      return CDOType.BYTE_ARRAY;
    }

    if (objectClass == Date.class || object instanceof Date)
    {
      return CDOType.DATE;
    }

    if (object instanceof EEnumLiteral)
    {
      return CDOType.ENUM_LITERAL;
    }

    if (objectClass == BigDecimal.class || object instanceof BigDecimal)
    {
      return CDOType.BIG_DECIMAL;
    }

    if (objectClass == BigInteger.class || object instanceof BigInteger)
    {
      return CDOType.BIG_INTEGER;
    }

    if (object instanceof Throwable)
    {
      return CDOType.EXCEPTION;
    }

    throw new IllegalArgumentException("Object type " + objectClass.getName() + " is not supported.");
  }

  /**
   * @since 2.0
   */
  public static CDOPackageInfo getPackageInfo(Object value, CDOPackageRegistry packageRegistry)
  {
    if (value instanceof EPackage)
    {
      return packageRegistry.getPackageInfo((EPackage)value);
    }

    if (value instanceof CDOPackageInfo)
    {
      CDOPackageInfo packageInfo = (CDOPackageInfo)value;
      if (packageInfo.getPackageUnit().getPackageRegistry() == packageRegistry)
      {
        return packageInfo;
      }
    }

    return null;
  }

  /**
   * Returns additional CDO infos for an {@link EClass}.
   * <p>
   * This operation is somewhat expensive because it synchronizes on the EClass and iterates over all adapters.
   * Whenever possible use {@link CDORevision#getClassInfo()} or <code>InternalCDOObject.getClassInfo()</code>.
   *
   * @since 2.0
   */
  public static CDOClassInfo getClassInfo(EClass eClass)
  {
    synchronized (eClass)
    {
      EList<Adapter> adapters = eClass.eAdapters();
      CDOClassInfo classInfo = (CDOClassInfo)EcoreUtil.getAdapter(adapters, CDOClassInfo.class);
      if (classInfo == null)
      {
        classInfo = new CDOClassInfoImpl();
        adapters.add(0, classInfo);
      }

      return classInfo;
    }
  }

  /**
   * Returns all persistent {@link EStructuralFeature features} of an {@link EClass}.
   * <p>
   * This operation is somewhat expensive because it synchronizes on the EClass and iterates over all adapters.
   *
   * @since 2.0
   * @deprecated As of 4.2 use <code>CDOModelUtil.getClassInfo(eClass).getAllPersistentFeatures()</code>.
   * @see #getClassInfo(EClass)
   */
  @Deprecated
  public static EStructuralFeature[] getAllPersistentFeatures(EClass eClass)
  {
    CDOClassInfo classInfo = getClassInfo(eClass);
    return classInfo.getAllPersistentFeatures();
  }

  /**
   * @since 2.0
   */
  public static CDOPackageUnit createPackageUnit()
  {
    return new CDOPackageUnitImpl();
  }

  /**
   * @since 2.0
   */
  public static CDOPackageInfo createPackageInfo()
  {
    return new CDOPackageInfoImpl();
  }

  /**
   * @since 3.0
   */
  public static EPackage readPackage(ExtendedDataInput in, ResourceSet resourceSet, boolean lookForResource) throws IOException
  {
    String uri = in.readString();
    boolean zipped = in.readBoolean();
    byte[] bytes = in.readByteArray();
    return EMFUtil.createEPackage(uri, bytes, zipped, resourceSet, lookForResource);
  }

  /**
   * @since 2.0
   */
  public static void writePackage(ExtendedDataOutput out, EPackage ePackage, boolean zipped, EPackage.Registry packageRegistry) throws IOException
  {
    checkCrossResourceURIs(ePackage);

    byte[] bytes = EMFUtil.getEPackageBytes(ePackage, zipped, packageRegistry);
    out.writeString(ePackage.getNsURI());
    out.writeBoolean(zipped);
    out.writeByteArray(bytes);
  }

  /**
   * @since 3.0
   */
  public static void checkCrossResourceURIs(EPackage ePackage)
  {
    TreeIterator<EObject> it = ePackage.eAllContents();
    while (it.hasNext())
    {
      EObject packageElement = it.next();

      if (packageElement instanceof EAnnotation)
      {
        // We don't need to validate the structure of annotations.
        // The applications that define annotations will have to take what they can get.
        it.prune();
      }
      else
      {
        for (EObject referencedElement : packageElement.eCrossReferences())
        {
          EObject referenceTarget = null;

          if (referencedElement.eIsProxy())
          {
            referencedElement = EcoreUtil.resolve(referencedElement, (ResourceSet)null);
            if (referencedElement.eIsProxy())
            {
              String msg = "Package '%s' contains unresolved proxy '%s'";
              msg = String.format(msg, ePackage.getNsURI(), ((InternalEObject)referencedElement).eProxyURI());
              throw new IllegalStateException(msg);
            }
          }

          if (referencedElement.eResource() != null && referencedElement.eResource() != packageElement.eResource())
          {
            // It's a reference into another resource.
            EPackage referencedPackage = null;
            if (referencedElement instanceof EClassifier)
            {
              referenceTarget = referencedElement;
              referencedPackage = ((EClassifier)referencedElement).getEPackage();
            }
            else if (referencedElement instanceof EStructuralFeature)
            {
              referenceTarget = referencedElement;
              EStructuralFeature feature = (EStructuralFeature)referencedElement;
              EClass ownerClass = (EClass)feature.eContainer();
              referencedPackage = ownerClass.getEPackage();
            }
            else if (referencedElement instanceof EGenericType)
            {
              EGenericType genType = (EGenericType)referencedElement;
              EClassifier c = genType.getEClassifier();
              if (c != null)
              {
                referenceTarget = c;
                referencedPackage = c.getEPackage();
              }
            }

            if (referencedPackage == null)
            {
              continue;
            }

            while (referencedPackage.getESuperPackage() != null)
            {
              referencedPackage = referencedPackage.getESuperPackage();
            }

            String resourceURI = referenceTarget.eResource().getURI().toString();
            if (!resourceURI.toString().equals(referencedPackage.getNsURI()))
            {
              String msg = "URI of the resource (%s) does not match the nsURI (%s) of the top-level package;\n"
                  + "this can be fixed by calling Resource.setURI(URI) after loading the packages,\n"
                  + "or by configuring a URI mapping from nsURI's to location URI's before loading the packages,\n"
                  + "and then loading them with their nsURI's";
              msg = String.format(msg, resourceURI, referencedPackage.getNsURI());
              throw new IllegalStateException(msg);
            }
          }
        }
      }
    }
  }

  /**
   * @since 4.10
   */
  public static void checkNoFeatureMaps(StringBuilder builder, EPackage ePackage, boolean checkFeatureMapEntries)
  {
    for (TreeIterator<EObject> it = ePackage.eAllContents(); it.hasNext();)
    {
      EObject packageElement = it.next();
      if (checkFeatureMapEntries && packageElement instanceof EClassifier)
      {
        EClassifier classifier = (EClassifier)packageElement;
        if (FeatureMapUtil.isFeatureMapEntry(classifier))
        {
          builder.append(String.format("Package '%s' contains feature map entry '%s'", ePackage.getNsURI(), classifier.getName()));
          builder.append("\n");
        }
      }
      else if (packageElement instanceof EStructuralFeature)
      {
        EStructuralFeature feature = (EStructuralFeature)packageElement;
        if (FeatureMapUtil.isFeatureMap(feature))
        {
          EClass eClass = feature.getEContainingClass();
          builder.append(String.format("Package '%s' contains feature map '%s.%s'", ePackage.getNsURI(), eClass.getName(), feature.getName()));
          builder.append("\n");
        }
      }
    }
  }

  /**
   * @since 4.10
   */
  public static void checkNoFeatureMaps(InternalCDOPackageUnit[] packageUnits, boolean checkFeatureMapEntries) throws CDOException
  {
    StringBuilder builder = new StringBuilder();
    for (InternalCDOPackageUnit packageUnit : packageUnits)
    {
      EPackage ePackage = packageUnit.getTopLevelPackageInfo().getEPackage();
      checkNoFeatureMaps(builder, ePackage, checkFeatureMapEntries);
    }

    if (builder.length() != 0)
    {
      throw new CDOException(builder.toString());
    }
  }

  /**
   * @since 4.0
   */
  public static Map<EClass, List<EClass>> getSubTypes(EPackage.Registry packageRegistry)
  {
    Map<EClass, List<EClass>> result = new HashMap<>();
    for (String nsURI : packageRegistry.keySet())
    {
      EPackage ePackage = packageRegistry.getEPackage(nsURI);
      getSubTypes(ePackage, result);
    }

    return result;
  }

  private static void getSubTypes(EPackage ePackage, Map<EClass, List<EClass>> result)
  {
    for (EClassifier classifier : ePackage.getEClassifiers())
    {
      if (classifier instanceof EClass)
      {
        EClass eClass = (EClass)classifier;
        getSubType(eClass, ROOT_TYPE, result);

        for (EClass eSuperType : eClass.getEAllSuperTypes())
        {
          getSubType(eClass, eSuperType, result);
        }
      }
    }
  }

  private static void getSubType(EClass eClass, EClass eSuperType, Map<EClass, List<EClass>> result)
  {
    if (eSuperType.eIsProxy())
    {
      OM.LOG.warn("getSubTypes encountered a proxy EClass which will be ignored: " + eSuperType);
      return;
    }

    List<EClass> list = result.get(eSuperType);
    if (list == null)
    {
      list = new ArrayList<>();
      result.put(eSuperType, list);
    }

    list.add(eClass);
  }
}
