/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     dclarke, mnorman - Dynamic Persistence
//       http://wiki.eclipse.org/EclipseLink/Development/Dynamic
//       (https://bugs.eclipse.org/bugs/show_bug.cgi?id=200045)
//
package org.eclipse.persistence.internal.dynamic;

//javase imports
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

//EclipseLink imports
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.dynamic.DynamicType;
import org.eclipse.persistence.exceptions.DynamicException;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;

/**
 * An EntityType provides a metadata facade into the EclipseLink
 * object-relational metadata (descriptors &amp; mappings) with specific knowledge
 * of the entity types being dynamic.
 *
 * @author dclarke, mnorman
 * @since EclipseLink 1.2
 */
public class DynamicTypeImpl implements DynamicType, Cloneable {

    protected ClassDescriptor descriptor;
    protected DynamicType parentType;
    protected DynamicPropertiesManager dpm;

    /**
     * These properties require initialization when a new instance is created.
     * This includes properties that are primitives as well as relationships
     * requiring indirection ValueHolders or collections.
     */
    protected Set<DatabaseMapping> mappingsRequiringInitialization = new HashSet<>();

    protected DynamicTypeImpl() {
        super();
    }

    /**
     * Creation of an EntityTypeImpl for an existing Descriptor with mappings.
     *
     */
    public DynamicTypeImpl(ClassDescriptor descriptor, DynamicType parentType) {
        this();
        this.descriptor = descriptor;
        this.parentType = parentType;
    }

    @Override
    public Object clone() {
        // clone yerself
        try {
            return super.clone();
        }
        catch (Exception exception) {
            throw new AssertionError(exception);
        }
    }

    @Override
    public ClassDescriptor getDescriptor() {
        return this.descriptor;
    }
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }


    public DynamicPropertiesManager getDynamicPropertiesManager() {
        return dpm;
    }

    public void setDynamicPropertiesManager(DynamicPropertiesManager dpm) {
        this.dpm = dpm;
    }

    @Override
    public DynamicType getParentType() {
        return this.parentType;
    }

    public List<DatabaseMapping> getMappings() {
        return getDescriptor().getMappings();
    }

    /**
     * @see DynamicType#getName()
     */
    @Override
    public String getName() {
        return getDescriptor().getAlias();
    }

    @Override
    public String getClassName() {
        return getDescriptor().getJavaClassName();
    }

    @Override
    public int getNumberOfProperties() {
        return dpm.getPropertyNames().size();
    }

    public Set<DatabaseMapping> getMappingsRequiringInitialization() {
        return mappingsRequiringInitialization;
    }


    public boolean isInitialized() {
        return getDescriptor().isFullyInitialized();
    }

    @Override
    public boolean containsProperty(String propertyName) {
        return dpm.contains(propertyName);
    }

    @Override
    public Class<? extends DynamicEntity> getJavaClass() {
        return getDescriptor().getJavaClass();
    }

    public DatabaseMapping getMapping(String propertyName) {
        DatabaseMapping mapping = getDescriptor().getMappingForAttributeName(propertyName);
        if (mapping == null) {
            throw DynamicException.invalidPropertyName(this, propertyName);
        }
        return mapping;
    }

    @Override
    public List<String> getPropertiesNames() {
        return dpm.getPropertyNames();
    }

    @Override
    public Class<?> getPropertyType(String propertyName) {
        return getMapping(propertyName).getAttributeClassification();
    }

    @Override
    public DynamicEntity newDynamicEntity() {
        DynamicEntity newDynamicEntity = (DynamicEntity)getDescriptor().getInstantiationPolicy().
            buildNewInstance();
        return newDynamicEntity;
    }

    /**
     * Ensure the value being set is supported by the mapping. If the mapping is
     * direct/basic and the mapping's type is primitive ensure the non-primitive
     * type is allowed.
     */
    public void checkSet(String propertyName, Object value) throws DynamicException {
        DatabaseMapping mapping = getMapping(propertyName);
        if (value == null) {
            if (mapping.isCollectionMapping() ||
                (mapping.getAttributeClassification() != null &&
                 mapping.getAttributeClassification().isPrimitive())) {
                throw DynamicException.invalidSetPropertyType(mapping, null);
            }
            return;
        }
        Class<?> expectedType = mapping.getAttributeClassification();
        if (mapping.isForeignReferenceMapping()) {
            if (mapping.isCollectionMapping()) {
                if (mapping.getContainerPolicy().isMapPolicy()) {
                    expectedType = Map.class;
                } else {
                    expectedType = Collection.class;
                }
            } else {
                expectedType = ((ForeignReferenceMapping)mapping).getReferenceClass();
            }
        }
        if (expectedType != null && expectedType.isPrimitive() && !value.getClass().isPrimitive()) {
            expectedType = Helper.getObjectClass(expectedType);
        }
        if (expectedType != null && !expectedType.isAssignableFrom(value.getClass())) {
            throw DynamicException.invalidSetPropertyType(mapping, value);
        }
    }

    @Override
    public int getPropertyIndex(String propertyName) {
        return dpm.getPropertyNames().indexOf(propertyName);
    }

    @Override
    public Class<?> getPropertyType(int propertyIndex) {
        return getDescriptor().getMappings().get(propertyIndex).getAttributeClassification();
    }

    @Override
    public String toString() {
        return "DynamicEntityType(" + getName() + ") - " + getDescriptor();
    }
}
