/*
 * 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.internal.sessions.remote.ObjectDescriptor;
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<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> 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();
    }
}
