/*
 * 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:
//     09/09/2011-2.3.1 Guy Pelletier
//       - 356197: Add new VPD type to MultitenantType
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     14/05/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
package org.eclipse.persistence.descriptors;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;

/**
 * A single table "striped" multitenant policy.
 *
 * @author Guy Pelletier
 * @since EclipseLink 2.3.1
 */
public class SingleTableMultitenantPolicy implements MultitenantPolicy {
    protected boolean includeTenantCriteria;
    protected ClassDescriptor descriptor;
    protected Map<DatabaseField, String> tenantDiscriminatorFields;
    protected Map<String, List<DatabaseField>> tenantDiscriminatorFieldsKeyedOnContext;

    public SingleTableMultitenantPolicy(ClassDescriptor desc) {
        descriptor = desc;
        includeTenantCriteria = true;
        tenantDiscriminatorFields = new HashMap<>(5);
        tenantDiscriminatorFieldsKeyedOnContext = new HashMap<>(5);
    }

    /**
     * INTERNAL:
     * Add the tenant discriminator fields to the row.
     */
    @Override
    public void addFieldsToRow(AbstractRecord row, AbstractSession session) {
        for (DatabaseField discriminatorField : tenantDiscriminatorFields.keySet()) {
            String property = tenantDiscriminatorFields.get(discriminatorField);
            Object propertyValue = session.getProperty(property);
            row.put(discriminatorField, propertyValue);
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public void addToTableDefinition(TableDefinition tableDefinition) {
        // Does nothing at this level.
    }

    /**
     * INTERNAL:
     */
    @Override
    public MultitenantPolicy clone(ClassDescriptor descriptor) {
        SingleTableMultitenantPolicy clonedPolicy = new SingleTableMultitenantPolicy(descriptor);
        clonedPolicy.includeTenantCriteria = includeTenantCriteria;
        clonedPolicy.tenantDiscriminatorFields = tenantDiscriminatorFields;
        return clonedPolicy;
    }

    /**
     * INTERNAL:
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * INTERNAL:
     * Add a tenant discriminator field to the policy.
     */
    public void addTenantDiscriminatorField(String property, DatabaseField field) {
        if (tenantDiscriminatorFields.containsKey(field)) {
            String currentProperty = tenantDiscriminatorFields.get(field);

            if (! currentProperty.equals(property)) {
                // Adding a different property for the same field is not
                // allowed. If it is the same we'll just ignore it.
                throw ValidationException.multipleContextPropertiesForSameTenantDiscriminatorFieldSpecified(getDescriptor().getJavaClassName(), field.getQualifiedName(), currentProperty, property);
            }
        } else {
            tenantDiscriminatorFields.put(field, property);

            if (! tenantDiscriminatorFieldsKeyedOnContext.containsKey(property)) {
                tenantDiscriminatorFieldsKeyedOnContext.put(property, new ArrayList<>());
            }

            tenantDiscriminatorFieldsKeyedOnContext.get(property).add(field);
        }
    }

    /**
     * INTERNAL:
     */
    public Map<DatabaseField, String> getTenantDiscriminatorFields() {
        return tenantDiscriminatorFields;
    }

    /**
     * INTERNAL:
     */
    public Map<String, List<DatabaseField>> getTenantDiscriminatorFieldsKeyedOnContext() {
        return tenantDiscriminatorFieldsKeyedOnContext;
    }

    /**
     * INTERNAL:
     * Return if this descriptor has specified some tenant discriminator fields.
     */
    public boolean hasTenantDiscriminatorFields() {
        return ! tenantDiscriminatorFields.isEmpty();
    }

    /**
     * INTERNAL:
     * Initialize the mappings as a separate step.
     * This is done as a separate step to ensure that inheritance has been first resolved.
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        if (hasTenantDiscriminatorFields()) {
            for (DatabaseField discriminatorField : tenantDiscriminatorFields.keySet()) {
                DatabaseMapping mapping = getDescriptor().getObjectBuilder().getMappingForField(discriminatorField);

                if (mapping != null && ! mapping.isReadOnly() && ! mapping.isMultitenantPrimaryKeyMapping()) {
                    throw ValidationException.nonReadOnlyMappedTenantDiscriminatorField(getDescriptor().getJavaClassName(), discriminatorField.getQualifiedName());
                }

                // Add the context property to the session set.
                session.addMultitenantContextProperty(tenantDiscriminatorFields.get(discriminatorField));
            }
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isSingleTableMultitenantPolicy() {
        return true;
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isTablePerMultitenantPolicy() {
        return false;
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isSchemaPerMultitenantPolicy() {
        return false;
    }

    /**
     * INTERNAL:
     * Subclasses that need to add field to an expresison should override this method.
     */
    @Override
    public void postInitialize(AbstractSession session) {
        if (includeTenantCriteria) {
            Expression expression = getDescriptor().getQueryManager().getAdditionalJoinExpression();
            ExpressionBuilder builder = (expression == null) ? new ExpressionBuilder() : expression.getBuilder();

            for (DatabaseField discriminatorField : tenantDiscriminatorFields.keySet()) {
                String property = tenantDiscriminatorFields.get(discriminatorField);
                // Add the tenant discriminator field context property as the parameter.
                // Do not initialize the database field with the property as it could be tenant.id
                // and we do not want to de-qualify it.
                DatabaseField newField = new DatabaseField();
                newField.setName(property, session.getPlatform());
                Expression tenantIdExpression = builder.and(builder.getField(discriminatorField).equal(builder.getProperty(newField)));

                if (expression == null) {
                    expression = tenantIdExpression;
                } else {
                    expression = expression.and(tenantIdExpression);
                }
            }

            getDescriptor().getQueryManager().setAdditionalJoinExpression(expression);
        }
    }

    /**
     * INTERNAL:
     * Allow the descriptor to initialize any dependencies on this session.
     */
    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        for (DatabaseField discriminatorField : tenantDiscriminatorFields.keySet()) {
            DatabaseField field = getDescriptor().buildField(discriminatorField);
            field.setKeepInRow(true);
            getDescriptor().getFields().add(field);
        }
    }

    /**
     * INTERNAL:
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    /**
     * ADVANCED:
     * Boolean used to indicate if the database requires the tenant criteria to
     * be added to the SELECT, UPDATE, and DELETE queries. By default this is
     * done but when set to false the queries will not be modified and it will
     * be up to the application or database to ensure that the correct criteria
     * is applied to all queries.
     *
     * @see org.eclipse.persistence.annotations.Multitenant
     */
    public void setIncludeTenantCriteria(boolean includeTenantCriteria) {
        this.includeTenantCriteria = includeTenantCriteria;
    }

    /**
     * INTERNAL:
     */
    public void setTenantDiscriminatorFields(Map<DatabaseField, String> tenantDiscriminatorFields) {
        this.tenantDiscriminatorFields = tenantDiscriminatorFields;
    }
}
