/*
 * 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 static org.eclipse.persistence.internal.helper.Helper.getShortClassName;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.dynamic.DynamicType;
import org.eclipse.persistence.exceptions.DynamicException;
import org.eclipse.persistence.indirection.IndirectContainer;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.descriptors.PersistenceEntity;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * This abstract class is used to represent an entity which typically is not
 * realized in Java code. In combination with the DynamicClassLoader ASM is used
 * to generate subclasses that will work within EclipseLink's framework. Since
 * no concrete fields or methods exist on this class the mappings used must be
 * customized to use a custom AttributeAccessor ({@link ValuesAccessor}).
 * <p>
 * <b>Type/Property Meta-model</b>: This dynamic entity approach also includes a
 * meta-model facade to simplify access to the types and property information so
 * that clients can more easily understand the model. Each
 * {@link DynamicTypeImpl} wraps the underlying EclipseLink
 * relational-descriptor and the {@link DynamicPropertiesManager} wraps each mapping.
 * The client application can use these types and properties to facilitate
 * generic access to the entity instances and are required for creating new
 * instances as well as for accessing the Java class needed for JPA and
 * EclipseLink native API calls.
 *
 * @author dclarke, mnorman
 * @since EclipseLink 1.2
 */
public abstract class DynamicEntityImpl implements DynamicEntity, PersistenceEntity,
        ChangeTracker, FetchGroupTracker {

    /**
     * Fetch properties manager.
     *
     * @return the dynamic properties manager
     */
    public abstract DynamicPropertiesManager fetchPropertiesManager();

    protected Map<String, PropertyWrapper> propertiesMap = new HashMap<>();

    /**
     * Instantiates a new dynamic entity impl.
     */
    protected DynamicEntityImpl() {
        postConstruct(); // life-cycle callback
    }

    /**
     * Gets the properties map.
     *
     * @return the properties map
     */
    public Map<String, PropertyWrapper> getPropertiesMap() {
        return propertiesMap;
    }

    /**
     * Post construct.
     */
    protected void postConstruct() {
        DynamicPropertiesManager dpm = fetchPropertiesManager();
        dpm.postConstruct(this);
    }

    /**
     * Gets internal impl class of {@link DynamicType}.
     *
     * @return Dynamic type of this entity
     * @throws DynamicException if type is null
     */
    public DynamicTypeImpl getType() throws DynamicException {
        DynamicType type = fetchPropertiesManager().getType();
        if (type == null) {
            throw DynamicException.entityHasNullType(this);
        }
        return (DynamicTypeImpl) type;
    }

    //DynamicEntity API
    /* (non-Javadoc)
     * @see org.eclipse.persistence.dynamic.DynamicEntity#get(java.lang.String)
     */
    @Override
    public <T> T get(String propertyName) throws DynamicException {
        DynamicPropertiesManager dpm = fetchPropertiesManager();
        if (dpm.contains(propertyName)) {
            if (_persistence_getFetchGroup() != null) {
                String errorMsg = _persistence_getFetchGroup().onUnfetchedAttribute(this,
                        propertyName);
                if (errorMsg != null) {
                    throw DynamicException.invalidPropertyName(dpm.getType(), propertyName);
                }
            }
            PropertyWrapper wrapper = propertiesMap.get(propertyName);
            if (wrapper == null) { // properties can be added after constructor is called
                wrapper = new PropertyWrapper();
                propertiesMap.put(propertyName, wrapper);
            }
            Object value = wrapper.getValue();
            // trigger any indirection
            if (value instanceof ValueHolderInterface) {
                value = ((ValueHolderInterface) value).getValue();
            }
            else if (value instanceof IndirectContainer) {
                value = ((IndirectContainer) value).getValueHolder().getValue();
            }
            try {
                return (T) value;
            } catch (ClassCastException cce) {
                ClassDescriptor descriptor = getType().getDescriptor();
                DatabaseMapping dm = null;
                if (descriptor != null) {
                    dm = descriptor.getMappingForAttributeName(propertyName);
                }
                else {
                    dm = new UnknownMapping(propertyName);
                }
                throw DynamicException.invalidGetPropertyType(dm, cce);
            }
        }
        else {
            throw DynamicException.invalidPropertyName(dpm.getType(), propertyName);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.dynamic.DynamicEntity#isSet(java.lang.String)
     */
    @Override
    public boolean isSet(String propertyName) throws DynamicException {
        if (fetchPropertiesManager().contains(propertyName)) {
            if (_persistence_getFetchGroup() != null &&
                    !_persistence_getFetchGroup().containsAttributeInternal(propertyName)) {
                return false;
            }
            PropertyWrapper wrapper = propertiesMap.get(propertyName);
            if (wrapper == null) { // properties can be added after constructor is called
                wrapper = new PropertyWrapper();
                propertiesMap.put(propertyName, wrapper);
            }
            return wrapper.isSet();
        }
        else {
            throw DynamicException.invalidPropertyName(fetchPropertiesManager().getType(),
                    propertyName);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.dynamic.DynamicEntity#set(java.lang.String, java.lang.Object)
     */
    @Override
    public DynamicEntity set(String propertyName, Object value) throws DynamicException {
        return set(propertyName, value, true);
    }

    /**
     * Sets the.
     *
     * @param propertyName the property name
     * @param value the value
     * @param firePropertyChange the fire property change
     * @return the dynamic entity
     * @throws DynamicException the dynamic exception
     */
    public DynamicEntity set(String propertyName, Object value, boolean firePropertyChange) throws DynamicException {
        DynamicPropertiesManager dpm = fetchPropertiesManager();
        dpm.checkSet(propertyName, value); // life-cycle callback
        if (_persistence_getFetchGroup() != null) {
            String errorMsg = _persistence_getFetchGroup().onUnfetchedAttributeForSet(this,
                    propertyName);
            if (errorMsg != null) {
                throw DynamicException.invalidPropertyName(dpm.getType(), propertyName);
            }
        }
        PropertyWrapper wrapper = propertiesMap.get(propertyName);
        if (wrapper == null) { // properties can be added after constructor is called
            wrapper = new PropertyWrapper();
            propertiesMap.put(propertyName, wrapper);
        }
        Object oldValue = null;
        Object wrapperValue = wrapper.getValue();
        if (wrapperValue instanceof ValueHolderInterface<?>) {
            ValueHolderInterface<Object> vh = (ValueHolderInterface<Object>) wrapperValue;
            if (vh.isInstantiated()) {
                oldValue = vh.getValue();
            }
            vh.setValue(value);
            wrapper.isSet(true);
        }
        else {
            oldValue = wrapperValue;
            wrapper.setValue(value);
            wrapper.isSet(true);
        }
        if (changeListener != null && firePropertyChange) {
            changeListener.propertyChange(new PropertyChangeEvent(this, propertyName,
                    oldValue, value));
        }
        return this;
    }

    // Made static final for performance reasons.
    public static final class PropertyWrapper {
        private Object value = null;
        private boolean isSet = false;

        /**
         * Instantiates a new property wrapper.
         */
        public PropertyWrapper() {
        }

        /**
         * Instantiates a new property wrapper.
         *
         * @param value the value
         */
        public PropertyWrapper(Object value) {
            setValue(value);
        }

        /**
         * Gets the value.
         *
         * @return the value
         */
        public Object getValue() {
            return value;
        }

        /**
         * Sets the value.
         *
         * @param value the new value
         */
        public void setValue(Object value) {
            this.value = value;
        }

        /**
         * Checks if is sets the.
         *
         * @return true, if is sets the
         */
        public boolean isSet() {
            return isSet;
        }

        /**
         * Checks if is set.
         *
         * @param isSet the is set
         */
        public void isSet(boolean isSet) {
            this.isSet = isSet;
        }

        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            if (isSet) {
                sb.append("[T]");
            }
            else {
                if (value == null) {
                    sb.append("[F]");
                }
                else {
                    sb.append("[d]");
                }
            }
            if (value == null) {
                sb.append("<null>");
            }
            else {
                sb.append(value.toString());
            }
            return sb.toString();
        }
    }

    // Made static final for performance reasons.
    static final class UnknownMapping extends DatabaseMapping {

        /**
         * Instantiates a new unknown mapping.
         *
         * @param propertyName the property name
         */
        public UnknownMapping(String propertyName) {
            setAttributeName(propertyName);
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#buildBackupClone(java.lang.Object, java.lang.Object, org.eclipse.persistence.internal.sessions.UnitOfWorkImpl)
         */
        @Override
        public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#buildClone(java.lang.Object, org.eclipse.persistence.internal.identitymaps.CacheKey, java.lang.Object, java.lang.Integer, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#buildCloneFromRow(org.eclipse.persistence.internal.sessions.AbstractRecord, org.eclipse.persistence.internal.queries.JoinedAttributeManager, java.lang.Object, org.eclipse.persistence.internal.identitymaps.CacheKey, org.eclipse.persistence.queries.ObjectBuildingQuery, org.eclipse.persistence.internal.sessions.UnitOfWorkImpl, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public void buildCloneFromRow(AbstractRecord databaseRow,
                JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery,
                UnitOfWorkImpl unitOfWork, AbstractSession executionSession) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#cascadePerformRemoveIfRequired(java.lang.Object, org.eclipse.persistence.internal.sessions.UnitOfWorkImpl, java.util.Map)
         */
        @Override
        public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow,
                Map visitedObjects) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#cascadeRegisterNewIfRequired(java.lang.Object, org.eclipse.persistence.internal.sessions.UnitOfWorkImpl, java.util.Map)
         */
        @Override
        public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow,
                Map visitedObjects) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#compareForChange(java.lang.Object, java.lang.Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public ChangeRecord compareForChange(Object clone, Object backup, ObjectChangeSet owner,
                AbstractSession session) {
            return null;
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#compareObjects(java.lang.Object, java.lang.Object, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public boolean compareObjects(Object firstObject, Object secondObject,
                AbstractSession session) {
            return false;
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#fixObjectReferences(java.lang.Object, java.util.Map, java.util.Map, org.eclipse.persistence.queries.ObjectLevelReadQuery, org.eclipse.persistence.sessions.remote.RemoteSession)
         */
        @Override
        public void fixObjectReferences(Object object, Map objectDescriptors, Map processedObjects,
                ObjectLevelReadQuery query, DistributedSession session) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#iterate(org.eclipse.persistence.internal.descriptors.DescriptorIterator)
         */
        @Override
        public void iterate(DescriptorIterator iterator) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#mergeChangesIntoObject(java.lang.Object, org.eclipse.persistence.internal.sessions.ChangeRecord, java.lang.Object, org.eclipse.persistence.internal.sessions.MergeManager, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source,
                MergeManager mergeManager, AbstractSession targetSession) {
        }

        /* (non-Javadoc)
         * @see org.eclipse.persistence.mappings.DatabaseMapping#mergeIntoObject(java.lang.Object, boolean, java.lang.Object, org.eclipse.persistence.internal.sessions.MergeManager, org.eclipse.persistence.internal.sessions.AbstractSession)
         */
        @Override
        public void mergeIntoObject(Object target, boolean isTargetUninitialized, Object source,
                MergeManager mergeManager, AbstractSession targetSession) {
        }
    }

    //PersistenceEntity API
    /**
     * Cache the primary key within the entity
     *
     * @see PersistenceEntity#_persistence_setId(Object)
     */
    private Object primaryKey;

    protected CacheKey cacheKey;

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.descriptors.PersistenceEntity#_persistence_getId()
     */
    @Override
    @SuppressWarnings("unchecked")
    public Object _persistence_getId() {
        return this.primaryKey;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.descriptors.PersistenceEntity#_persistence_setId(java.lang.Object)
     */
    @Override
    @SuppressWarnings("unchecked")
    public void _persistence_setId(Object pk) {
        this.primaryKey = pk;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.descriptors.PersistenceEntity#_persistence_getCacheKey()
     */
    @Override
    public CacheKey _persistence_getCacheKey() {
        return this.cacheKey;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.descriptors.PersistenceEntity#_persistence_setCacheKey(org.eclipse.persistence.internal.identitymaps.CacheKey)
     */
    @Override
    public void _persistence_setCacheKey(CacheKey cacheKey) {
        this.cacheKey = cacheKey;
    }

    //ChangeTracker API
    /**
     * ChangeListener used for attribute change tracking processed in the
     * property. Set through
     * {@link ChangeTracker#_persistence_setPropertyChangeListener(PropertyChangeListener)}
     */
    private PropertyChangeListener changeListener = null;

    /* (non-Javadoc)
     * @see org.eclipse.persistence.descriptors.changetracking.ChangeTracker#_persistence_getPropertyChangeListener()
     */
    @Override
    public PropertyChangeListener _persistence_getPropertyChangeListener() {
        return this.changeListener;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.descriptors.changetracking.ChangeTracker#_persistence_setPropertyChangeListener(java.beans.PropertyChangeListener)
     */
    @Override
    public void _persistence_setPropertyChangeListener(PropertyChangeListener listener) {
        this.changeListener = listener;
    }

    //FetchGroup API
    /**
     * FetchGroup cached by
     * {@link FetchGroupTracker#_persistence_setFetchGroup(FetchGroup)}
     */
    private FetchGroup fetchGroup;
    /**
     * {@link FetchGroupTracker#_persistence_setShouldRefreshFetchGroup(boolean)}
     */
    private boolean refreshFetchGroup = false;

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_getFetchGroup()
     */
    @Override
    public FetchGroup _persistence_getFetchGroup() {
        return this.fetchGroup;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_setFetchGroup(org.eclipse.persistence.queries.FetchGroup)
     */
    @Override
    public void _persistence_setFetchGroup(FetchGroup group) {
        this.fetchGroup = group;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_setShouldRefreshFetchGroup(boolean)
     */
    @Override
    public void _persistence_setShouldRefreshFetchGroup(boolean shouldRefreshFetchGroup) {
        this.refreshFetchGroup = shouldRefreshFetchGroup;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_shouldRefreshFetchGroup()
     */
    @Override
    public boolean _persistence_shouldRefreshFetchGroup() {
        return this.refreshFetchGroup;
    }

    /**
     * Return true if the attribute is in the fetch group being tracked.
     *
     * @param attribute the attribute
     * @return true, if successful
     */
    @Override
    public boolean _persistence_isAttributeFetched(String attribute) {
        return this.fetchGroup == null || this.fetchGroup.containsAttributeInternal(attribute);
    }

    /**
     * Reset all attributes of the tracked object to the un-fetched state with
     * initial default values.
     */
    @Override
    public void _persistence_resetFetchGroup() {
    }

    /**
     * Session cached by
     * {@link FetchGroupTracker#_persistence_setSession(Session)}
     */
    private Session session;

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_getSession()
     */
    @Override
    public Session _persistence_getSession() {
        return this.session;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.queries.FetchGroupTracker#_persistence_setSession(org.eclipse.persistence.sessions.Session)
     */
    @Override
    public void _persistence_setSession(Session session) {
        this.session = session;
    }

    /**
     * String representation of the dynamic entity using the entity type name
     * and the primary key values - something like {Emp 10} or {Phone 234-5678 10}.
     *
     * @return the string
     */
    @Override
    public String toString() {
        // this will print something like {Emp 10} or {Phone 234-5678 10}
        StringBuilder sb = new StringBuilder(20);
        sb.append('{');
        sb.append(getShortClassName(this.getClass()));
        if (primaryKey != null) {
            sb.append(' ');
            sb.append(primaryKey);
        }
        sb.append('}');
        return sb.toString();
    }
}
