/*
 * Copyright (c) 2011, 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:
//     James Sutherland (Oracle) - initial API and implementation
//      //     30/05/2012-2.4 Guy Pelletier
//       - 354678: Temp classloader is still being used during metadata processing
package org.eclipse.persistence.descriptors.partitioning;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
 * PUBLIC:
 * ValuePartitioningPolicy partitions access to a database cluster by a field value from the object,
 * such as the object's location, or tenant.
 * Each value is assigned a specific server.
 * All write or read request for object's with that value are sent to the server.
 * If a query does not include the field as a parameter, then it can either be sent
 * to all server's and unioned, or left to the sesion's default behavior.
 * @author James Sutherland
 * @since EclipseLink 2.2
 */
public class ValuePartitioningPolicy extends FieldPartitioningPolicy {

    /** Store the value partitions. Each partition maps a value to a connectionPool. */
    protected Map<Object, String> partitions = new HashMap<>();
    /** Store the value partitions by name. Initialized at runtime. */
    protected Map<String, String> partitionNames = new HashMap<>();

    /** The type name of the partition value names. Initialized at runtime */
    protected String partitionValueTypeName;

    /** The type of the partition values. Initialized from the type name at runtime. */
    protected Class<?> partitionValueType;

    /** Use to track order for compute UCP index. */
    protected List<String> orderedPartitions = new ArrayList<>();

    /** The default connection pool is used for any unmapped values. */
    protected String defaultConnectionPool;

    public ValuePartitioningPolicy() {
        super();
    }

    public ValuePartitioningPolicy(String partitionField) {
        super(partitionField);
    }

    public ValuePartitioningPolicy(String partitionField, boolean unionUnpartitionableQueries) {
        super(partitionField, unionUnpartitionableQueries);
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings 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) {
        if (partitionValueType == null && partitionValueTypeName != null) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        partitionValueType = AccessController.doPrivileged(new PrivilegedClassForName<>(partitionValueTypeName, true, classLoader));
                    } catch (PrivilegedActionException e) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(partitionValueTypeName, e.getException());
                    }
                } else {
                    partitionValueType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(partitionValueTypeName, true, classLoader);
                }
            } catch (Exception exception) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(partitionValueTypeName, exception);
            }
        }

        // Once we know we have a partition value type we can convert our partition names.
        if (partitionValueType != null) {
            for (String valueName : this.partitionNames.keySet()) {
                Object value = initObject(partitionValueType, valueName);
                if (getPartitions().containsKey(value)) {
                    throw ValidationException.duplicatePartitionValue(getName(), value);
                }
                addPartition(value, partitionNames.get(valueName));
            }
        }
    }

    /**
     * Convert the string value to the class type.
     * This will handle numbers, string, dates, and most other classes.
     */
    private <T> T initObject(Class<T> type, String value) {
        return ConversionManager.getDefaultManager().convertObject(value, type);
    }

    /**
     * INTERNAL:
     */
    public void setPartitionValueTypeName(String partitionValueTypeName) {
        this.partitionValueTypeName = partitionValueTypeName;
    }

    public List<String> getOrderedPartitions() {
        return orderedPartitions;
    }

    public void setOrderedPartitions(List<String> orderedPartitions) {
        this.orderedPartitions = orderedPartitions;
    }

    /**
     * PUBLIC:
     * Return the default connection pool used for any unmapped values.
     */
    public String getDefaultConnectionPool() {
        return defaultConnectionPool;
    }

    /**
     * PUBLIC:
     * Set the default connection pool used for any unmapped values.
     */
    public void setDefaultConnectionPool(String defaultConnectionPool) {
        this.defaultConnectionPool = defaultConnectionPool;
    }

    /**
     * PUBLIC:
     * Return the value partitions.
     * Each partition maps a value to a connectionPool.
     */
    public Map<Object, String> getPartitions() {
        return partitions;
    }

    /**
     * PUBLIC:
     * Set the value partitions.
     * Each partition maps a value to a connectionPool.
     */
    public void setPartitions(Map<Object, String> partitions) {
        this.partitions = partitions;
    }

    /**
     * PUBLIC:
     * Add the value partition.
     */
    public void addPartition(Object value, String connectionPool) {
        getPartitions().put(value, connectionPool);
        getOrderedPartitions().add(connectionPool);
    }

    /**
     * INTERNAL:
     * Add partition values by name (will be initialized at runtime with the
     * real class loader).
     */
    public void addPartitionName(String valueName, String connectionPool) {
        this.partitionNames.put(valueName, connectionPool);
    }

    /**
     * INTERNAL:
     * Get a connection from one of the pools in a round robin rotation fashion.
     */
    @Override
    public List<Accessor> getConnectionsForQuery(AbstractSession session, DatabaseQuery query, AbstractRecord arguments) {
        Object value = arguments.get(this.partitionField);
        if (value == null) {
            if (this.unionUnpartitionableQueries) {
                // Use all connections.
                List<Accessor> accessors = new ArrayList<>(this.partitions.size());
                for (String poolName : this.partitions.values()) {
                    accessors.add(getAccessor(poolName, session, query, false));
                }
                return accessors;
            } else {
                // Use default behavior.
                return null;
            }
        }
        // Use the mapped connection pool.
        List<Accessor> accessors = new ArrayList<>(1);
        String poolName = this.partitions.get(value);
        if (poolName == null) {
            if (this.defaultConnectionPool == null) {
                // Use default behavior.
                return null;
            }
            poolName = this.defaultConnectionPool;
        }
        if (session.getPlatform().hasPartitioningCallback()) {
            // UCP support.
            session.getPlatform().getPartitioningCallback().setPartitionId(getOrderedPartitions().indexOf(poolName));
            return null;
        }
        accessors.add(getAccessor(poolName, session, query, false));
        return accessors;
    }

    /**
     * INTERNAL:
     * Allow for the persist call to assign the partition.
     */
    @Override
    public void partitionPersist(AbstractSession session, Object object, ClassDescriptor descriptor) {
        Object value = extractPartitionValueForPersist(session, object, descriptor);
        if (value == null) {
            return;
        }
        String poolName = this.partitions.get(value);
        if (poolName == null) {
            return;
        }
        if (session.getPlatform().hasPartitioningCallback()) {
            // UCP support.
            session.getPlatform().getPartitioningCallback().setPartitionId(getOrderedPartitions().indexOf(poolName));
        } else {
            getAccessor(poolName, session, null, false);
        }
    }
}
