/*
 * 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:
//     Oracle - initial API and implementation
//     IBM - Bug 537795: CASE THEN and ELSE scalar expression Constants should not be casted to CASE operand type
package org.eclipse.persistence.nosql.adapters.mongo;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Vector;

import jakarta.resource.cci.InteractionSpec;
import jakarta.resource.cci.MappedRecord;
import jakarta.resource.cci.Record;

import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.eis.EISAccessor;
import org.eclipse.persistence.eis.EISDescriptor;
import org.eclipse.persistence.eis.EISException;
import org.eclipse.persistence.eis.EISPlatform;
import org.eclipse.persistence.eis.interactions.EISInteraction;
import org.eclipse.persistence.eis.interactions.MappedInteraction;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.databaseaccess.QueryStringCall;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoInteractionSpec;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoOperation;
import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoRecord;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.internal.expressions.FieldExpression;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.LogicalExpression;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.QueryKeyExpression;
import org.eclipse.persistence.internal.expressions.RelationExpression;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.expressions.SQLStatement;
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.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.foundation.AbstractCompositeCollectionMapping;
import org.eclipse.persistence.mappings.foundation.AbstractCompositeDirectCollectionMapping;
import org.eclipse.persistence.mappings.foundation.AbstractCompositeObjectMapping;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sessions.DatabaseRecord;

import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;

/**
 * Platform for Mongo database.
 *
 * @author James
 * @since EclipseLink 2.4
 */
public class MongoPlatform extends EISPlatform {

    /** Mongo interaction spec properties. */
    public static final String OPERATION = "mongo.operation";
    public static final String COLLECTION = "mongo.collection";
    public static final String OPTIONS = "mongo.options";
    public static final String READ_PREFERENCE = "mongo.read-preference";
    public static final String WRITE_CONCERN = "mongo.write-concern";
    public static final String SKIP = "mongo.skip";
    public static final String LIMIT = "mongo.limit";
    public static final String BATCH_SIZE = "mongo.batch-size";

    /** Configure if like should be SQL or regex. */
    protected boolean isLikeRegex;

    /**
     * Default constructor.
     */
    public MongoPlatform() {
        super();
        setIsMappedRecordSupported(true);
        setIsIndexedRecordSupported(false);
        setIsDOMRecordSupported(true);
        setSupportsLocalTransactions(true);
    }

    /**
     * Mongo does not support all Java types.
     * Convert unsupported types to string.
     */
    @Override
    public void setValueInRecord(String key, Object value, MappedRecord record, EISAccessor accessor) {
        Object recordValue = value;
        if ((value instanceof BigDecimal) || (value instanceof BigInteger)) {
            recordValue = getConversionManager().convertObject(value, ClassConstants.STRING);
        }
        record.put(key, recordValue);
    }

    /**
     * Return if regex should be used for like.
     */
    public boolean isLikeRegex() {
        return isLikeRegex;
    }

    /**
     * Set if regex should be used for like.
     */
    public void setIsLikeRegex(boolean isLikeRegex) {
        this.isLikeRegex = isLikeRegex;
    }

    /**
     * Allow the platform to build the interaction spec based on properties defined in the interaction.
     */
    @Override
    public InteractionSpec buildInteractionSpec(EISInteraction interaction) {
        InteractionSpec spec = interaction.getInteractionSpec();
        if (spec == null) {
            MongoInteractionSpec mongoSpec = new MongoInteractionSpec();
            Object operation = interaction.getProperty(OPERATION);
            if (interaction.isQueryStringCall()) {
                mongoSpec.setCode(((QueryStringCall)interaction).getQueryString());
                operation = MongoOperation.EVAL;
            }
            if (operation == null) {
                throw new EISException("'" + OPERATION + "' property must be set on the query's interation.");
            }
            if (operation instanceof String) {
                operation = MongoOperation.valueOf((String)operation);
            }
            mongoSpec.setOperation((MongoOperation)operation);
            Object collection = interaction.getProperty(COLLECTION);
            if (collection != null) {
                mongoSpec.setCollection((String)collection);
            }

            // Allows setting of read preference as a property.
            Object preference = interaction.getProperty(READ_PREFERENCE);
            if (preference instanceof ReadPreference) {
                mongoSpec.setReadPreference((ReadPreference)preference);
            } else if (preference instanceof String) {
                String constant = (String)preference;
                if (constant.equals("PRIMARY")) {
                    mongoSpec.setReadPreference(ReadPreference.primary());
                } else if (constant.equals("SECONDARY")) {
                    mongoSpec.setReadPreference(ReadPreference.secondary() );
                } else {
                    throw new EISException("Invalid read preference property value: " + constant);
                }
            }

            // Allows setting of write concern as a property.
            Object concern = interaction.getProperty(WRITE_CONCERN);
            if (concern instanceof WriteConcern) {
                mongoSpec.setWriteConcern((WriteConcern)concern);
            } else if (concern instanceof String) {
                String constant = (String)concern;
                if (constant.equals("FSYNC_SAFE")) {
                    mongoSpec.setWriteConcern(WriteConcern.FSYNC_SAFE);
                } else if (constant.equals("JOURNAL_SAFE")) {
                    mongoSpec.setWriteConcern(WriteConcern.JOURNAL_SAFE);
                } else if (constant.equals("MAJORITY")) {
                    mongoSpec.setWriteConcern(WriteConcern.MAJORITY);
                } else if (constant.equals("NONE")) {
                    mongoSpec.setWriteConcern(/* WriteConcern.NONE */ new WriteConcern("none"));
                } else if (constant.equals("NORMAL")) {
                    mongoSpec.setWriteConcern(WriteConcern.NORMAL);
                } else if (constant.equals("REPLICAS_SAFE")) {
                    mongoSpec.setWriteConcern(WriteConcern.REPLICAS_SAFE);
                } else if (constant.equals("SAFE")) {
                    mongoSpec.setWriteConcern(WriteConcern.SAFE);
                } else {
                    throw new EISException("Invalid read preference property value: " + constant);
                }
            }

            // Allows setting of options as a property.
            Object options = interaction.getProperty(OPTIONS);
            if (options instanceof Number) {
                mongoSpec.setOptions(((Number)options).intValue());
            } else if (options instanceof String) {
                mongoSpec.setOptions(Integer.parseInt(((String)options)));
            }

            // Allows setting of skip as a property.
            Object skip = interaction.getProperty(SKIP);
            if (skip instanceof Number) {
                mongoSpec.setSkip(((Number)skip).intValue());
            } else if (skip instanceof String) {
                mongoSpec.setSkip(Integer.parseInt(((String)skip)));
            }

            // Allows setting of limit as a property.
            Object limit = interaction.getProperty(LIMIT);
            if (limit instanceof Number) {
                mongoSpec.setLimit(((Number)limit).intValue());
            } else if (skip instanceof String) {
                mongoSpec.setLimit(Integer.parseInt(((String)limit)));
            }

            // Allows setting of batchSize as a property.
            Object batchSize = interaction.getProperty(BATCH_SIZE);
            if (batchSize instanceof Number) {
                mongoSpec.setBatchSize(((Number)batchSize).intValue());
            } else if (skip instanceof String) {
                mongoSpec.setBatchSize(Integer.parseInt(((String)batchSize)));
            }

            spec = mongoSpec;
        }
        return spec;
    }


    /**
     * For updates a separate translation record is required.
     * The output row is used for this.
     */
    @Override
    public Record createOutputRecord(EISInteraction interaction, AbstractRecord translationRow, EISAccessor accessor) {
        if (((interaction.getInteractionSpec() != null) && ((MongoInteractionSpec)interaction.getInteractionSpec()).getOperation() == MongoOperation.UPDATE)
                || ((interaction.getProperty(OPERATION) != null)
                        && ((interaction.getProperty(OPERATION) == MongoOperation.UPDATE) || (interaction.getProperty(OPERATION).equals(MongoOperation.UPDATE.name()))))) {
            return (Record)interaction.createRecordElement(interaction.getInputRecordName(), translationRow, accessor);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Allow the platform to initialize the CRUD queries to defaults.
     * Configure the CRUD operations using GET/PUT and DELETE.
     */
    @Override
    public void initializeDefaultQueries(DescriptorQueryManager queryManager, AbstractSession session) {
        // Insert
        if (!queryManager.hasInsertQuery()) {
            EISInteraction call = new MappedInteraction();
            call.setProperty(MongoPlatform.OPERATION, MongoOperation.INSERT);
            call.setProperty(MongoPlatform.COLLECTION, ((EISDescriptor)queryManager.getDescriptor()).getDataTypeName());
            queryManager.setInsertCall(call);
        }

        // Update
        if (!queryManager.hasUpdateQuery()) {
            EISInteraction call = new MappedInteraction();
            call.setProperty(MongoPlatform.OPERATION, MongoOperation.UPDATE);
            call.setProperty(MongoPlatform.COLLECTION, ((EISDescriptor)queryManager.getDescriptor()).getDataTypeName());
            queryManager.setUpdateCall(call);
        }

        // Read
        if (!queryManager.hasReadObjectQuery()) {
            MappedInteraction call = new MappedInteraction();
            call.setProperty(MongoPlatform.OPERATION, MongoOperation.FIND);
            call.setProperty(MongoPlatform.COLLECTION, ((EISDescriptor)queryManager.getDescriptor()).getDataTypeName());
            for (DatabaseField field : queryManager.getDescriptor().getPrimaryKeyFields()) {
                call.addArgument(field.getName());
            }
            queryManager.setReadObjectCall(call);
        }

        // Delete
        if (!queryManager.hasDeleteQuery()) {
            MappedInteraction call = new MappedInteraction();
            call.setProperty(MongoPlatform.OPERATION, MongoOperation.REMOVE);
            call.setProperty(MongoPlatform.COLLECTION, ((EISDescriptor)queryManager.getDescriptor()).getDataTypeName());
            for (DatabaseField field : queryManager.getDescriptor().getPrimaryKeyFields()) {
                call.addArgument(field.getName());
            }
            queryManager.setDeleteCall(call);
        }
    }

    /**
     * INTERNAL:
     * Override this method to throw an exception by default.
     * Platforms that support dynamic querying can override this to generate an EISInteraction.
     */
    @Override
    public DatasourceCall buildCallFromStatement(SQLStatement statement, DatabaseQuery query, AbstractSession session) {
        if (query.isObjectLevelReadQuery()) {
            ObjectLevelReadQuery readQuery = (ObjectLevelReadQuery)query;
            MappedInteraction interaction = new MappedInteraction();
            interaction.setProperty(OPERATION, MongoOperation.FIND);
            interaction.setProperty(COLLECTION, ((EISDescriptor)query.getDescriptor()).getDataTypeName());
            if (readQuery.getFirstResult() > 0) {
                interaction.setProperty(SKIP, readQuery.getFirstResult());
            }
            if (readQuery.getMaxRows() > 0) {
                interaction.setProperty(LIMIT, readQuery.getMaxRows());
            }
            if (readQuery.getFetchSize() > 0) {
                interaction.setProperty(BATCH_SIZE, readQuery.getMaxRows());
            }
            DatabaseRecord row = new DatabaseRecord();
            if (statement.getWhereClause() != null) {
                appendExpressionToQueryRow(statement.getWhereClause(), row, query);
            }
            if (readQuery.hasOrderByExpressions()) {
                DatabaseRecord sort = new DatabaseRecord();
                for (Expression orderBy : readQuery.getOrderByExpressions()) {
                    appendExpressionToSortRow(orderBy, sort, query);
                }
                row.put(MongoRecord.SORT, sort);
            }
            if (readQuery.isReportQuery()) {
                DatabaseRecord select = new DatabaseRecord();
                for (Object field : ((SQLSelectStatement)statement).getFields()) {
                    if (field instanceof DatabaseField) {
                        select.put((DatabaseField)field, 1);
                    } else if (field instanceof Expression) {
                        Object value = extractValueFromExpression((Expression)field, readQuery);
                        if (!(value instanceof DatabaseField)) {
                            throw new EISException("Query too complex for Mongo translation, only field selects are supported in query: " + query);
                        }
                        select.put((DatabaseField)value, 1);
                    }
                }
                row.put("$select", select);
            }
            interaction.setInputRow(row);
            return interaction;
        }
        throw new EISException("Query too complex for Mongo translation, only select queries are supported in query: " + query);
    }

    /**
     * Append the expression and recursively to the query row.
     */
    protected void appendExpressionToQueryRow(Expression expression, AbstractRecord row, DatabaseQuery query) {
        if (expression.isRelationExpression()) {
            RelationExpression relation = (RelationExpression)expression;
            Object left = extractValueFromExpression(relation.getFirstChild(), query);
            Object right = extractValueFromExpression(relation.getSecondChild(), query);
            if (relation.getOperator().getSelector() == ExpressionOperator.Equal) {
                row.put(left, right);
            } else {
                DatabaseRecord nested = new DatabaseRecord();
                if (relation.getOperator().getSelector() == ExpressionOperator.GreaterThan) {
                    nested.put("$gt", right);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.LessThan) {
                    nested.put("$lt", right);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.LessThanEqual) {
                    nested.put("$lte", right);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.GreaterThanEqual) {
                    nested.put("$gte", right);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.NotEqual) {
                    nested.put("$ne", right);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.In) {
                    nested.put("$in", right);
                    row.put(left, nested);
                } else if (relation.getOperator().getSelector() == ExpressionOperator.NotIn) {
                    nested.put("$nin", right);
                    row.put(left, nested);
                } else {
                    throw new EISException("Query too complex for Mongo translation, relation [" + expression + "] not supported in query: " + query);
                }
                row.put(left, nested);
            }
        } else if (expression.isLogicalExpression()) {
            LogicalExpression logic = (LogicalExpression)expression;
            DatabaseRecord first = new DatabaseRecord();
            DatabaseRecord second = new DatabaseRecord();
            appendExpressionToQueryRow(logic.getFirstChild(), first, query);
            appendExpressionToQueryRow(logic.getSecondChild(), second, query);
            List nested = new Vector();
            nested.add(first);
            nested.add(second);
            if (logic.getOperator().getSelector() == ExpressionOperator.And) {
                row.put("$and", nested);
            } else if (logic.getOperator().getSelector() == ExpressionOperator.Or) {
                row.put("$or", nested);
            } else {
                throw new EISException("Query too complex for Mongo translation, logic [" + expression + "] not supported in query: " + query);
            }
        } else if (expression.isFunctionExpression()) {
            FunctionExpression function = (FunctionExpression)expression;
            if (function.getOperator().getSelector() == ExpressionOperator.Like) {
                Object left = extractValueFromExpression(function.getChildren().get(0), query);
                Object right = extractValueFromExpression(function.getChildren().get(1), query);
                if (!(right instanceof String)) {
                    throw new EISException("Query too complex for Mongo translation, like with [" + right + "] not supported in query: " + query);
                }
                String pattern = (String)right;
                DatabaseRecord nested = new DatabaseRecord();
                if (!this.isLikeRegex) {
                    pattern = Helper.convertLikeToRegex(pattern);
                }
                nested.put("$regex", pattern);
                row.put(left, nested);
            } else if (function.getOperator().getSelector() == ExpressionOperator.Not) {
                // Detect situation 'not(a = b)' and change it to '(a != b)'
                Expression expr = function.getChildren().get(0);
                if (expr.isRelationExpression()) {
                    RelationExpression relation = (RelationExpression)expr;
                    Object left = extractValueFromExpression(relation.getFirstChild(), query);
                    Object right = extractValueFromExpression(relation.getSecondChild(), query);

                    DatabaseRecord nested = new DatabaseRecord();
                    if (expr.getOperator().getSelector() == ExpressionOperator.Equal) {
                        nested.put("$ne", right);
                    } else {
                        nested.put("not", right);
                    }

                    row.put(left, nested);
                } else {
                    throw new EISException("Query too complex for Mongo translation, function [" + expression + "] not supported in query: " + query);
                }
            } else {
                throw new EISException("Query too complex for Mongo translation, function [" + expression + "] not supported in query: " + query);
            }
        } else {
            throw new EISException("Query too complex for Mongo translation, expression [" + expression + "] not supported in query: " + query);
        }
    }

    /**
     * Append the order by expression to the sort row.
     */
    protected void appendExpressionToSortRow(Expression expression, AbstractRecord row, DatabaseQuery query) {
        if (expression.isFunctionExpression()) {
            FunctionExpression function = (FunctionExpression)expression;
            if (function.getOperator().getSelector() == ExpressionOperator.Ascending) {
                Object field = extractValueFromExpression(function.getChildren().get(0), query);
                row.put(field, 1);
            } else if (function.getOperator().getSelector() == ExpressionOperator.Descending) {
                Object field = extractValueFromExpression(function.getChildren().get(0), query);
                row.put(field, -1);
            } else {
                throw new EISException("Query too complex for Mongo translation, order by [" + expression + "] not supported in query: " + query);
            }
        } else {
            Object field = extractValueFromExpression(expression, query);
            row.put(field, 1);
        }
    }

    /**
     * Extract the field or constant value from the comparison expression.
     */
    protected Object extractValueFromExpression(Expression expression, DatabaseQuery query) {
        Object value = null;
        expression.getBuilder().setSession(query.getSession());
        if (expression.isQueryKeyExpression()) {
            QueryKeyExpression queryKeyExpression = (QueryKeyExpression)expression;
            value = queryKeyExpression.getField();
            if ((queryKeyExpression.getMapping() != null) && queryKeyExpression.getMapping().getDescriptor().isDescriptorTypeAggregate()) {
                String name = queryKeyExpression.getField().getName();
                while (queryKeyExpression.getBaseExpression().isQueryKeyExpression()
                        && (((QueryKeyExpression)queryKeyExpression.getBaseExpression()).getMapping().isAbstractCompositeObjectMapping()
                        || ((QueryKeyExpression)queryKeyExpression.getBaseExpression()).getMapping().isAbstractCompositeCollectionMapping()
                        || ((QueryKeyExpression)queryKeyExpression.getBaseExpression()).getMapping().isAbstractCompositeDirectCollectionMapping())) {
                    queryKeyExpression = (QueryKeyExpression)queryKeyExpression.getBaseExpression();
                    if (queryKeyExpression.getMapping().isAbstractCompositeObjectMapping()) {
                        name = queryKeyExpression.getMapping().getField().getName() + "." + name;
                    } else if (queryKeyExpression.getMapping().isAbstractCompositeCollectionMapping()) {
                        name = queryKeyExpression.getMapping().getField().getName() + "." + name;
                    } else if (queryKeyExpression.getMapping().isAbstractCompositeDirectCollectionMapping()) {
                        name = queryKeyExpression.getMapping().getField().getName() + "." + name;
                    }
                }
                DatabaseField field = new DatabaseField();
                field.setName(name);
                value = field;
            }
        } else if (expression.isFieldExpression()) {
            value = ((FieldExpression)expression).getField();
        } else if (expression.isConstantExpression()) {
            value = ((ConstantExpression)expression).getValue();
            if (((ConstantExpression)expression).getLocalBase() != null) {
                value = ((ConstantExpression)expression).getLocalBase().getFieldValue(value, query.getSession());
            }
        } else if (expression.isParameterExpression()) {
            value = query.getTranslationRow().get(((ParameterExpression)expression).getField());
            if (((ParameterExpression)expression).getLocalBase() != null) {
                value = ((ParameterExpression)expression).getLocalBase().getFieldValue(value, query.getSession());
            }
        } else {
            throw new EISException("Query too complex for Mongo translation, comparison of [" + expression + "] not supported in query: " + query);
        }
        if (value instanceof List) {
            List values = (List)value;
            for (int index = 0; index < values.size(); index++) {
                Object element = values.get(index);
                if (element instanceof Expression) {
                    element = extractValueFromExpression((Expression)element, query);
                    values.set(index, element);
                }
            }
        }
        return value;
    }

    /**
     * Do not prepare dynamic queries, as the translation row is required.
     */
    @Override
    public boolean shouldPrepare(DatabaseQuery query) {
        return (query.getDatasourceCall() instanceof EISInteraction);
    }

    /**
     * INTERNAL:
     * Create platform-default Sequence
     */
    @Override
    protected Sequence createPlatformDefaultSequence() {
        return new OIDSequence();
    }
}
