/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.queries;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Iterator;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetMethod;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.querykeys.QueryKey;

/**
 * <p><b>Purpose</b>: The abstract class for ContainerPolicy's whose container class implements
 * a container interface.
 *
 * @see CollectionContainerPolicy
 * @see MapContainerPolicy
 */
public abstract class InterfaceContainerPolicy extends ContainerPolicy {

    /** The concrete container class. */
    protected Class containerClass;
    protected String containerClassName;

    /** The method which will return a clone of an instance of the containerClass. */
    protected transient Method cloneMethod;

    /**
     * INTERNAL:
     * Construct a new policy.
     */
    protected InterfaceContainerPolicy() {
        super();
    }

    /**
     * INTERNAL:
     * Construct a new policy for the specified class.
     */
    protected InterfaceContainerPolicy(Class containerClass) {
        setContainerClass(containerClass);
    }

    /**
     * INTERNAL:
     * Construct a new policy for the specified class name.
     */
    protected InterfaceContainerPolicy(String containerClassName) {
        setContainerClassName(containerClassName);
    }

    /**
     * INTERNAL:
     * Return if the policy is equal to the other.
     * By default if they are the same class, they are considered equal.
     * This is used for query parse caching.
     */
    @Override
    public boolean equals(Object object) {
        return super.equals(object) && getContainerClass().equals(((InterfaceContainerPolicy)object).getContainerClass());
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        Class containerClass = getContainerClass();
        result = 31 * result + (containerClass != null ? containerClass.hashCode() : 0);
        return result;
    }

    /**
     * INTERNAL:
     * Return a clone of the specified container.
     */
    @Override
    public Object cloneFor(Object container) {
        if (container == null) {
            return null;
        }

        Method cloneMethod;
        Class<?> javaClass = container.getClass();
        if (javaClass == getContainerClass()) {
            cloneMethod = getCloneMethod();
        } else {
            // container may be a superclass of the concrete container class
            // so we have to use the right clone method...
            cloneMethod = getCloneMethod(javaClass);
        }
        return invokeCloneMethodOn(cloneMethod, container);
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this ContainerPolicy to actual class-based
     * settings. This method is used when converting a project that has been built
     * with class names to a project with classes.
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);
        if (getContainerClassName() == null){
            return;
        }
        Class containerClass = null;
        try{
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    containerClass = AccessController.doPrivileged(new PrivilegedClassForName<>(getContainerClassName(), true, classLoader));
                } catch (PrivilegedActionException exception) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(getContainerClassName(), exception.getException());
                }
            } else {
                containerClass = PrivilegedAccessHelper.getClassForName(getContainerClassName(), true, classLoader);
            }
        } catch (ClassNotFoundException exception) {
            throw ValidationException.classNotFoundWhileConvertingClassNames(getContainerClassName(), exception);
        }
        setContainerClass(containerClass);
    }

    /**
     * INTERNAL:
     * Creates a CollectionChangeEvent for the container
     */
    @Override
    public CollectionChangeEvent createChangeEvent(Object collectionOwner, String propertyName, Object collectionChanged, Object elementChanged, int changeType, Integer index, boolean isChangeApplied) {
        return new CollectionChangeEvent(collectionOwner, propertyName, collectionChanged, elementChanged, changeType, index, false, isChangeApplied);// make the remove change event fire.
    }

    /**
     * INTERNAL:
     * Create a query key that links to the map key
     * InterfaceContainerPolicy does not support maps, so this method will return null
     * subclasses will extend this method.
     */
    public QueryKey createQueryKeyForMapKey() {
        return null;
    }

    /**
     * INTERNAL:
     * Return the 'clone()' Method for the container class.
     * Lazy initialization is used, so we can serialize these things.
     */
    public Method getCloneMethod() {
        if (cloneMethod == null) {
            setCloneMethod(getCloneMethod(getContainerClass()));
        }
        return cloneMethod;
    }

    private static final class ClassWeakReference extends WeakReference<Class> {
        private final int hash;

        ClassWeakReference(Class referent) {
            super(referent);
            hash = referent.hashCode();
        }

        ClassWeakReference(Class referent, ReferenceQueue<Class> referenceQueue) {
            super(referent, referenceQueue);
            hash = referent.hashCode();
        }

        @Override
        public int hashCode() {
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }

            if (obj instanceof ClassWeakReference) {
                return get() == ((ClassWeakReference) obj).get();
            }

            return false;
        }

        @Override
        public String toString() {
            Class referent = get();
            return new StringBuilder("ClassWeakReference: ").append(referent == null ? null : referent).toString();
        }
    }

    private static final ReferenceQueue<Class> refQueue = new ReferenceQueue<>();
    private static final ConcurrentHashMap<ClassWeakReference, Method> cloneMethodCache = new ConcurrentHashMap<>();
    
    /**
     * INTERNAL:
     * Return the 'clone()' Method for the specified class.
     * Return null if the method does not exist anywhere in the hierarchy
     */
    protected Method getCloneMethod(Class javaClass) {
        for (Object key; (key = refQueue.poll()) != null;) {
            cloneMethodCache.remove(key);
        }
        Method cloneMethod = cloneMethodCache.get(new ClassWeakReference(javaClass));
        if (cloneMethod != null) {
            return cloneMethod;
        }
        try {
            // This must not be set "accessible" - clone() must be public, and some JVM's do not allow access to JDK classes.
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    cloneMethod = AccessController.doPrivileged(new PrivilegedGetMethod(javaClass, "clone", null, false));
                } catch (PrivilegedActionException exception) {
                    throw QueryException.methodDoesNotExistInContainerClass("clone", javaClass);
                }
            } else {
                cloneMethod = PrivilegedAccessHelper.getMethod(javaClass, "clone", null, false);
            }
        } catch (NoSuchMethodException ex) {
            throw QueryException.methodDoesNotExistInContainerClass("clone", javaClass);
        }

        cloneMethodCache.put(new ClassWeakReference(javaClass, refQueue), cloneMethod);
        return cloneMethod;
    }

    /**
     * INTERNAL:
     * Returns the container class to be used with this policy.
     */
    @Override
    public Class getContainerClass() {
        return containerClass;
    }

    @Override
    public String getContainerClassName() {
        if ((containerClassName == null) && (containerClass != null)) {
            containerClassName = containerClass.getName();
        }
        return containerClassName;
    }

    /**
     * INTERNAL:
     * Return the DatabaseField that represents the key in a DirectMapMapping.  If the
     * keyMapping is not a DirectMapping, this will return null.
     */
    public DatabaseField getDirectKeyField(CollectionMapping mapping) {
        return null;
    }

    public abstract Class getInterfaceType();

    /**
     * INTERNAL:
     * Return whether the iterator has more objects,
     */
    @Override
    public boolean hasNext(Object iterator) {
        return ((Iterator)iterator).hasNext();
    }

    /**
     * INTERNAL:
     * Invoke the specified clone method on the container,
     * handling the necessary exceptions.
     */
    protected Object invokeCloneMethodOn(Method method, Object container) {
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    return AccessController.doPrivileged(new PrivilegedMethodInvoker(method, container, null));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof IllegalAccessException) {
                        throw QueryException.cannotAccessMethodOnObject(method, container);
                    } else {
                        throw QueryException.methodInvocationFailed(method, container, throwableException);
                    }
                }
            } else {
                return PrivilegedAccessHelper.invokeMethod(method, container, null);
            }
        } catch (IllegalAccessException ex1) {
            throw QueryException.cannotAccessMethodOnObject(method, container);
        } catch (InvocationTargetException ex2) {
            throw QueryException.methodInvocationFailed(method, container, ex2);
        }
    }

    /**
     * INTERNAL:
     * Return whether a map key this container policy represents is an attribute
     * By default this method will return false since only subclasses actually represent maps.
     */
    public boolean isMapKeyAttribute(){
        return false;
    }

    /**
     * INTERNAL:
     * Validate the container type.
     */
    @Override
    public boolean isValidContainerType(Class containerType) {
        return Helper.classImplementsInterface(containerType, getInterfaceType());
    }

    /**
     * INTERNAL:
     * Return the next object on the queue.
     * Valid for some subclasses only.
     */
    @Override
    protected Object next(Object iterator) {
        return ((Iterator)iterator).next();
    }

    /**
     * INTERNAL:
     * Set the Method that will return a clone of an instance of the containerClass.
     */
    public void setCloneMethod(Method cloneMethod) {
        this.cloneMethod = cloneMethod;
    }

    /**
     * INTERNAL:
     * Set the class to use as the container.
     */
    @Override
    public void setContainerClass(Class containerClass) {
        this.containerClass = containerClass;
        initializeConstructor();
    }

    @Override
    public void setContainerClassName(String containerClassName) {
        this.containerClassName = containerClassName;
    }

    /**
     * INTERNAL:
     * Return a container populated with the contents of the specified Vector.
     */
    @Override
    public Object buildContainerFromVector(Vector vector, AbstractSession session) {
        // PERF: If a Vector policy just return the original.
        if (this.containerClass == ClassConstants.Vector_class) {
            return vector;
        }
        return super.buildContainerFromVector(vector, session);
    }

    @Override
    protected Object toStringInfo() {
        return getContainerClass();
    }
}
