/*
 * 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
    @SuppressWarnings({"unchecked"})
    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<?>) {
            @SuppressWarnings({"unchecked"})
            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);
            }
            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
    public Object _persistence_getId() {
        return this.primaryKey;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.descriptors.PersistenceEntity#_persistence_setId(java.lang.Object)
     */
    @Override
    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();
    }
}
