/*
 * 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.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Comparator;
import java.lang.reflect.Constructor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;

/**
 * <p><b>Purpose</b>: A SortedCollectionContainerPolicy is ContainerPolicy whose
 * container class implements the SortedInterface interface.
 * Added for BUG # 3233263
 * </p>
 * <p><b>Responsibilities</b>:
 * Provide the functionality to operate on an instance of a SortedSet.</p>
 *
 * @see ContainerPolicy
 * @see MapContainerPolicy
 */
public class SortedCollectionContainerPolicy extends CollectionContainerPolicy {
    protected Comparator m_comparator = null;
    protected Class  comparatorClass = null ;
    protected String comparatorClassName = null;


    /**
     * INTERNAL:
     * Construct a new policy.
     */
    public SortedCollectionContainerPolicy() {
        super();
    }

    /**
     * INTERNAL:
     * Construct a new policy for the specified class.
     */
    public SortedCollectionContainerPolicy(Class containerClass) {
        super(containerClass);
    }


    /**
     * INTERNAL:
     * Construct a new policy for the specified class name.
     */
    public SortedCollectionContainerPolicy(String containerClassName) {
        super(containerClassName);
    }

    /**
     * INTERNAL:
     * Sets a comparator object for this policy to use when instantiating
     * a new SortedSet object.
     */
    public void setComparator(Comparator comparator) {
        m_comparator = comparator;
    }

    /**
     * INTERNAL:
     * Sets a comparator class for this policy to use when instantiating
     * a new SortedSet object.
     */
    public void setComparatorClass(Class comparatorClass) {
        if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
            m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
        }else{
            throw ValidationException.invalidComparatorClass(comparatorClass.getName());
        }
        this.comparatorClass=comparatorClass;
    }

    /**
     * INTERNAL:
     * Sets a comparator class name for this policy to use when instantiating
     * a new SortedSet object.
     */
    public void setComparatorClassName(String comparatorClassName) {
        this.comparatorClassName=comparatorClassName;
    }


    /**
     * INTERNAL:
     * Return the stored comparator
     */
    public Comparator getComparator() {
        return m_comparator;
    }

    /**
     * INTERNAL:
     * Return the stored comparator class
     */
    public Class getComparatorClass() {
        return comparatorClass;
    }


    /**
     * INTERNAL:
     * return stored comparator class name
     */
    public String getComparatorClassName() {
        if (this.m_comparator!=null){
            return this.m_comparator.getClass().getName();
        }else if (this.comparatorClass!=null){
            return this.comparatorClass.getName();
        }else if (this.comparatorClassName!=null){
            return this.comparatorClassName;
        }else{
            return null;
        }
    }

    /**
     * INTERNAL
     * Override from ContainerPolicy. Need to maintain the comparator in the
     * new instance
     */
    @Override
    public Object containerInstance() {
        try {
            if(m_comparator==null && comparatorClass!=null){
                if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
                    m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
                }else{
                    throw ValidationException.invalidComparatorClass(comparatorClass.getName());
                }
            }
            if (m_comparator != null) {
                Object[] arguments = new Object[] { m_comparator };
                Class[] constructClass = new Class[] { Comparator.class };
                Constructor constructor = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(getContainerClass(), constructClass, false));
                        return AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, arguments));
                    } catch (PrivilegedActionException exception) {
                        throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException());
                    }
                } else {
                    constructor = PrivilegedAccessHelper.getConstructorFor(getContainerClass(), constructClass, false);
                    return PrivilegedAccessHelper.invokeConstructor(constructor, arguments);
                }
            } else {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(getContainerClass()));
                    } catch (PrivilegedActionException exception) {
                        throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), exception.getException());
                    }
                } else {
                    return PrivilegedAccessHelper.newInstanceFromClass(getContainerClass());
                }
            }
        } catch (Exception ex) {
            throw QueryException.couldNotInstantiateContainerClass(getContainerClass(), ex);
        }
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this SortedCollectionContainerPolicy 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(m_comparator==null){
             if(comparatorClass==null){
                 if(comparatorClassName!=null){
                      Class comparatorClass = Helper.getClassFromClasseName(comparatorClassName, classLoader);
                      if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
                          m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
                      }else{
                          throw ValidationException.invalidComparatorClass(comparatorClassName);
                      }
                 }
             }else{
                 if(Helper.classImplementsInterface(comparatorClass, java.util.Comparator.class)){
                     m_comparator=(Comparator)Helper.getInstanceFromClass(comparatorClass);
                 }else{
                     throw ValidationException.invalidComparatorClass(comparatorClass.getName());
                 }
             }
        }
    }

}
