/*
 * Copyright (c) 1998, 2020 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.descriptors.changetracking;

import java.beans.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.mappings.foundation.*;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.exceptions.ValidationException;

/**
 * <p>
 * <b>Purpose</b>: Define a listener for attribute change tracking.
 * <p>
 * <b>Description</b>: Listener is notified on a PropertyChangeEvent from the object it belongs to.
 * <p>
 * <b>Responsibilities</b>: Set the flag to true and build ObjectChangeSet that includes the
 * ChangeRecords for the changed attributes.
 */
public class AttributeChangeListener extends ObjectChangeListener {
    protected transient ClassDescriptor descriptor;
    protected transient UnitOfWorkImpl uow;
    protected org.eclipse.persistence.internal.sessions.ObjectChangeSet objectChangeSet;
    protected Object owner;

    /**
     * INTERNAL:
     * Create a AttributeChangeListener with a descriptor and unit of work
     */
    public AttributeChangeListener(ClassDescriptor descriptor, UnitOfWorkImpl uow, Object owner) {
        super();
        this.descriptor = descriptor;
        this.uow = uow;
        this.owner = owner;
    }

    /**
     * INTERNAL:
     * Return the object change set associated with this listener
     */
    public org.eclipse.persistence.internal.sessions.ObjectChangeSet getObjectChangeSet() {
        return objectChangeSet;
    }

    /**
     * INTERNAL:
     * Return the object change set associated with this listener
     */
    public void setObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet changeSet) {
        this.objectChangeSet = changeSet;
    }

    /**
     * INTERNAL:
     * Return the descriptor associated with this listener
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * INTERNAL:
     * Set the descriptor associated with this listener
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    /**
     * INTERNAL:
     * Return the unit of work associated with this listener
     */
    public UnitOfWorkImpl getUnitOfWork() {
        return uow;
    }

    /**
     * INTERNAL:
     * Set the unit of work associated with this listener
     */
    public void setUnitOfWork(UnitOfWorkImpl uow) {
        this.uow = uow;
    }

    /**
     * PUBLIC:
     * This method creates the object change set if necessary.  It also creates/updates
     * the change record based on the new value.  Object should check the if newValue and
     * oldValue are identical.  If they are identical, do not create PropertyChangeEvent
     * and call this method.
     */
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (this.ignoreEvents){
            return;
        }
        internalPropertyChange(evt);
    }

    /**
     * INTERNAL:
     * This method marks the object as changed.  This method is only
     * called by EclipseLink
     */
    @Override
    public void internalPropertyChange(PropertyChangeEvent evt) {
        if (evt.getNewValue() == evt.getOldValue()) {
            return;
        }

        DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(evt.getPropertyName());
        //Bug#4127952 Throw an exception indicating there is no mapping for the property name.
        if (mapping == null) {
            throw ValidationException.wrongPropertyNameInChangeEvent(owner.getClass(), evt.getPropertyName());
        }
        if (mapping instanceof AbstractDirectMapping || mapping instanceof AbstractTransformationMapping) {
            //If both newValue and oldValue are null, or newValue is not null and newValue equals oldValue, don't build ChangeRecord
            if (((evt.getNewValue() == null) && (evt.getOldValue() == null)) || ((evt.getNewValue() != null) && (evt.getNewValue()).equals(evt.getOldValue()))) {
                return;
            }
        }

        super.internalPropertyChange(evt);

        if (uow.getUnitOfWorkChangeSet() == null) {
            uow.setUnitOfWorkChangeSet(new UnitOfWorkChangeSet(uow));
        }
        if (objectChangeSet == null) {//only null if new or if in a new UOW
            //add to tracker list to prevent GC of clone if using weak references
            //put it in here so that it only occurs on the 1st change for a particular UOW
            uow.addToChangeTrackedHardList(owner);
            objectChangeSet = getDescriptor().getObjectBuilder().createObjectChangeSet(owner, (UnitOfWorkChangeSet) uow.getUnitOfWorkChangeSet(), false, uow);
        }

        if (evt.getClass().equals(ClassConstants.PropertyChangeEvent_Class)) {
            mapping.updateChangeRecord(evt.getSource(), evt.getNewValue(), evt.getOldValue(), objectChangeSet, getUnitOfWork());
        } else if (evt.getClass().equals(ClassConstants.CollectionChangeEvent_Class) || (evt.getClass().equals(ClassConstants.MapChangeEvent_Class))) {
            mapping.updateCollectionChangeRecord((CollectionChangeEvent)evt, objectChangeSet, getUnitOfWork());
        } else {
            throw ValidationException.wrongChangeEvent(evt.getClass());
        }
    }

    /**
     * INTERNAL:
     * Clear the changes in this listener
     */
    @Override
    public void clearChanges(boolean forRefresh) {
        super.clearChanges(forRefresh);
        if (forRefresh && this.objectChangeSet != null){
            this.objectChangeSet.clear(true);
        }
        this.objectChangeSet = null;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "(" + getObjectChangeSet() + ")";
    }
}
