/*
 * Copyright (c) 2011, 2019 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.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
 * PUBLIC:
 * RangePartitioningPolicy partitions access to a database cluster by a field value from the object,
 * such as the object's id, location, or tenant.
 * Each server is assigned a range of values.
 * 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 RangePartitioningPolicy extends FieldPartitioningPolicy {

    protected List<RangePartition> partitions = new ArrayList<>();

    public RangePartitioningPolicy() {
        super();
    }

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

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

    public RangePartitioningPolicy(String partitionField, RangePartition... partitions) {
        this(partitionField);
        for (RangePartition partition : partitions) {
            addPartition(partition);
        }
    }

    /**
     * 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) {
        for (RangePartition rangePartition : partitions) {
            rangePartition.convertClassNamesToClasses(classLoader);
        }
    }

    /**
     * PUBLIC:
     * Return the range partitions.
     * Each partition represents a range of value to route to a connection pool.
     * Range values should not overlap.
     */
    public List<RangePartition> getPartitions() {
        return partitions;
    }

    /**
     * PUBLIC:
     * Set the range partitions.
     * Each partition represents a range of value to route to a connection pool.
     * Range values should not overlap.
     */
    public void setPartitions(List<RangePartition> partitions) {
        this.partitions = partitions;
    }

    /**
     * PUBLIC:
     * Add the range partition.
     */
    public void addPartition(String connectionPool, Comparable startValue, Comparable endValue) {
        getPartitions().add(new RangePartition(connectionPool, startValue, endValue));
    }

    /**
     * PUBLIC:
     * Add the range partition.
     */
    public void addPartition(RangePartition partition) {
        getPartitions().add(partition);
    }

    /**
     * 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);
        List<Accessor> accessors = null;
        if (value == null) {
            if (this.unionUnpartitionableQueries) {
                accessors = new ArrayList<>(this.partitions.size());
            } else {
                return null;
            }
        } else {
            accessors = new ArrayList<>(1);
        }
        int size = this.partitions.size();
        for (int index = 0; index < size; index++) {
            RangePartition partition = this.partitions.get(index);
            if ((value == null) || partition.isInRange(value)) {
                if (session.getPlatform().hasPartitioningCallback()) {
                    // UCP support.
                    session.getPlatform().getPartitioningCallback().setPartitionId(index);
                    return null;
                }
                accessors.add(getAccessor(partition.getConnectionPool(), session, query, false));
                if (value != null) {
                    break;
                }
            }
        }
        if (accessors.isEmpty()) {
            return null;
        }
        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;
        }
        int size = this.partitions.size();
        for (int index = 0; index < size; index++) {
            RangePartition partition = this.partitions.get(index);
            if (partition.isInRange(value)) {
                if (session.getPlatform().hasPartitioningCallback()) {
                    // UCP support.
                    session.getPlatform().getPartitioningCallback().setPartitionId(index);
                } else {
                    getAccessor(partition.getConnectionPool(), session, null, false);
                }
                return;
            }
        }
    }
}
