/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. All rights reserved.
 * Copyright (c) 2012, 2021 SAP. 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:
// SAP AG - Initial implementation, enhancement bug 380226
//
// This code is being developed under INCUBATION and is not currently included
// in the automated EclipseLink build. The API in this code may change, or
// may never be included in the product. Please provide feedback through mailing
// lists or the bug database.
package org.eclipse.persistence.platform.database;

import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.tools.schemaframework.FieldDefinition;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;

/**
 * <b>Database Platform for SAP HANA</b> <br>
 *
 * <p>
 * <b>Feature Testing</b><br>
 * ----------------------
 * <ul>
 * <li>DDL Generation - Succeeds
 * <li>Outer Join - Succeeds
 * <li>Subquery - Succeeds
 * <li>Stored Procedure Calls - Not supported
 * <li>Stored Procedure Generation - Not supported
 * <li>Native Sequences/Identifier fields - Succeeds
 * <li>JPA Bulk Update/Delete - Succeeds with Limitations
 * <li>Batch Reading - Succeeds
 * <li>Batch Writing - Succeeds
 * <li>Pessimistic Locking - Succeeds with Limitations
 * <li>First Result/Limit - Succeeds with Limitations
 * <li>Expression Framework - Succeeds with Limitations
 * <li>Delimiters - Succeeds
 * <li>Auto Detection - Succeeds
 * </ul>
 * <br>
 * <p>
 * <b>Limitations</b><br>
 * ----------------
 * <ul>
 * <li>Reserved SQL keywords cannot be used as table, column or sequence names. Use a different
 * name, or enclose the name in double quotes. For example: @Column(name="\"LANGUAGE\"")
 * <li>Pessimistic locking adds 'FOR UPDATE' to the SELECT statement, and cannot be used with
 * queries that use DISTINCT.
 * <li>Pessimistic locking cannot be used with queries that select from multiple tables.
 * <li>The LockNoWait option of Pessimistic Locking cannot be used; it is ignored when specified
 * (i.e. only 'FOR UPDATE' is added to the SELECT statement).
 * <li>Bulk update and delete operations that require multiple tables to be accessed cannot be used
 * (e.g. bulk operation on an entity that is part of an inheritance hierarchy, UpdateAll and
 * DeleteAll queries).
 * {@literal <li>'= NULL' and '<> NULL'} cannot be used for null comparisons in the WHERE clause.
 * Use 'IS (NOT) NULL' instead.
 * <li>Scrollable cursors are not supported.
 * <li>Query timeouts are not supported.
 * </ul>
 *
 * @author Reiner Singer (SAP AG), Sabine Heider (SAP AG)
 */
public final class HANAPlatform extends DatabasePlatform {

    private static final long serialVersionUID = 1L;

    private static final int MAX_VARTYPE_LENGTH = 2000;

    public HANAPlatform() {
        super();
        this.pingSQL = "SELECT 1 FROM DUMMY";
    }

    @Override
    public boolean isHANA() {
        return true;
    }

    @Override
    public boolean usesStringBinding() {
        return false;
    }

    @Override
    public boolean requiresUniqueConstraintCreationOnTableCreate() {
        return true;
    }

    @Override
    public boolean isForUpdateCompatibleWithDistinct() {
        return false;
    }

    @Override
    public boolean supportsIndividualTableLocking() {
        return false;
    }

    @Override
    protected Hashtable<Class<?>, FieldTypeDefinition> buildFieldTypes() {
        final Hashtable<Class<?>, FieldTypeDefinition> fieldTypeMapping = new Hashtable<>();
        fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("SMALLINT", false)); // TODO
                                                                                         // boolean
        fieldTypeMapping.put(Number.class, new FieldTypeDefinition("DOUBLE", false));
        fieldTypeMapping.put(Short.class, new FieldTypeDefinition("SMALLINT", false));
        fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("INTEGER", false));
        fieldTypeMapping.put(Long.class, new FieldTypeDefinition("BIGINT", false));
        fieldTypeMapping.put(Float.class, new FieldTypeDefinition("FLOAT", false));
        fieldTypeMapping.put(Double.class, new FieldTypeDefinition("DOUBLE", false));

        fieldTypeMapping.put(BigInteger.class, new FieldTypeDefinition("DECIMAL", 34));
        fieldTypeMapping.put(BigDecimal.class,
                new FieldTypeDefinition("DECIMAL", 34).setLimits(34, -34, 34));

        fieldTypeMapping.put(Character.class, new FieldTypeDefinition("NCHAR", 1));
        fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("NVARCHAR", 255));
        fieldTypeMapping.put(char[].class, new FieldTypeDefinition("NVARCHAR", 255));
        fieldTypeMapping.put(String.class, new FieldTypeDefinition("NVARCHAR", 255));

        fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("SMALLINT", false));
        fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("VARBINARY", 255));
        fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("VARBINARY", 255));

        fieldTypeMapping.put(Blob.class, new FieldTypeDefinition("BLOB", false));
        fieldTypeMapping.put(Clob.class, new FieldTypeDefinition("NCLOB", false));

        fieldTypeMapping.put(Date.class, new FieldTypeDefinition("DATE", false));
        fieldTypeMapping.put(Time.class, new FieldTypeDefinition("TIME", false));
        fieldTypeMapping.put(Timestamp.class, new FieldTypeDefinition("TIMESTAMP", false));
        return fieldTypeMapping;
    }

    @Override
    /**
     * EclipseLink does not support length dependent type mapping.
     * Map varchar types with length > MAX_VARCHAR_UNICODE_LENGTH to CLOB (i.e clob); shorter types to NVARCHAR (n)
     * See also bugs 317597, 317448
     */
    protected void printFieldTypeSize(Writer writer, FieldDefinition field,
            FieldTypeDefinition fieldType) throws IOException {
        String typeName = fieldType.getName();
        if ("NVARCHAR".equals(typeName)) {
            if (field.getSize() > MAX_VARTYPE_LENGTH) {
                fieldType = new FieldTypeDefinition("NCLOB", false);
            }
        } else if ("VARBINARY".equals(typeName)) {
            if (field.getSize() > MAX_VARTYPE_LENGTH || field.getSize() == 0) {
                fieldType = new FieldTypeDefinition("BLOB", false);
            }
        }

        super.printFieldTypeSize(writer, field, fieldType);
        if (fieldType.getTypesuffix() != null) {
            writer.append(" " + fieldType.getTypesuffix());
        }
    }

    @Override
    protected void initializePlatformOperators() {
        super.initializePlatformOperators();
        this.addOperator(HANAPlatform.createConcatExpressionOperator());
        this.addOperator(HANAPlatform.createNullifOperator());
        this.addOperator(HANAPlatform.createTodayExpressionOperator());
        this.addOperator(HANAPlatform.createCurrentDateExpressionOperator());
        this.addOperator(HANAPlatform.createCurrentTimeExpressionOperator());
        this.addOperator(HANAPlatform.createLogOperator());
        this.addOperator(HANAPlatform.createLocateOperator());
        this.addOperator(HANAPlatform.createLocate2Operator());
        this.addOperator(HANAPlatform.createVarianceOperator());
        this.addNonBindingOperator(HANAPlatform.createNullValueOperator());
    }

    private static ExpressionOperator createConcatExpressionOperator() {
        return ExpressionOperator.simpleLogicalNoParens(ExpressionOperator.Concat, "||");
    }

    /**
     * Creates the expression operator representing the JPQL function current_timestamp as defined
     * by 4.6.17.2.3 of the JPA 2.0 specification
     *
     * @return the expression operator representing the JPQL function current_timestamp as defined
     *         by 4.6.17.2.3 of the JPA 2.0 specification
     */
    private static ExpressionOperator createTodayExpressionOperator() {
        return ExpressionOperator.simpleLogicalNoParens(ExpressionOperator.Today,
                "CURRENT_TIMESTAMP");
    }

    /**
     * Creates the expression operator representing the JPQL function current_date as defined by
     * 4.6.17.2.3 of the JPA 2.0 specification
     *
     * @return the expression operator representing the JPQL function current_date as defined by
     *         4.6.17.2.3 of the JPA 2.0 specification
     */
    private static ExpressionOperator createCurrentDateExpressionOperator() {
        return ExpressionOperator.simpleLogicalNoParens(ExpressionOperator.CurrentDate,
                "CURRENT_DATE");
    }

    /**
     * Creates the expression operator representing the JPQL function current_timestamp as defined
     * by 4.6.17.2.3 of the JPA 2.0 specification
     *
     * @return the expression operator representing the JPQL function current_timestamp as defined
     *         by 4.6.17.2.3 of the JPA 2.0 specification
     */
    private static ExpressionOperator createCurrentTimeExpressionOperator() {
        return ExpressionOperator.simpleLogicalNoParens(ExpressionOperator.CurrentTime,
                "CURRENT_TIME");
    }

    /**
     * Creates the expression operator representing the JPQL function variance
     *
     * @return the expression operator representing the JPQL function variance
     */
    private static ExpressionOperator createVarianceOperator() {
        return ExpressionOperator.simpleAggregate(ExpressionOperator.Variance, "VAR", "variance");
    }

    /**
     * Create the log operator for this platform
     */
    private static ExpressionOperator createLogOperator() {
        ExpressionOperator result = new ExpressionOperator();
        result.setSelector(ExpressionOperator.Log);
        List<String> v = new ArrayList<>(2);
        v.add("LOG(10,");
        v.add(")");
        result.printsAs(v);
        result.bePrefix();
        result.setNodeClass(FunctionExpression.class);
        return result;
    }

    /**
     * INTERNAL: Build locate operator i.e. LOCATE("ob", t0.F_NAME)
     */
    public static ExpressionOperator createLocateOperator() {
        ExpressionOperator expOperator = ExpressionOperator.simpleTwoArgumentFunction(
                ExpressionOperator.Locate, "INSTR");
        int[] argumentIndices = new int[2];
        argumentIndices[0] = 0;
        argumentIndices[1] = 1;
        expOperator.setArgumentIndices(argumentIndices);
        expOperator.setIsBindingSupported(false);
        return expOperator;
    }

    /**
     * INTERNAL: Build locate operator with 3 params i.e. LOCATE("coffee", t0.DESCRIP, 4). Last
     * parameter is a start at.
     */
    public static ExpressionOperator createLocate2Operator() {
        ExpressionOperator expOperator = ExpressionOperator.simpleThreeArgumentFunction(
                ExpressionOperator.Locate2, "INSTR");
        int[] argumentIndices = new int[3];
        argumentIndices[0] = 0;
        argumentIndices[1] = 1;
        argumentIndices[2] = 2;
        expOperator.setArgumentIndices(argumentIndices);
        expOperator.setIsBindingSupported(false);
        return expOperator;
    }

    private static ExpressionOperator createNullifOperator() {
        ExpressionOperator exOperator = new ExpressionOperator();
        exOperator.setType(ExpressionOperator.FunctionOperator);
        exOperator.setSelector(ExpressionOperator.NullIf);
        List<String> v = new ArrayList<>(4);
        v.add(" (CASE WHEN ");
        v.add(" = ");
        v.add(" THEN NULL ELSE ");
        v.add(" END) ");
        exOperator.printsAs(v);
        exOperator.bePrefix();
        int[] indices = { 0, 1, 0 };
        exOperator.setArgumentIndices(indices);
        exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
        return exOperator;
    }

    private static ExpressionOperator createNullValueOperator() {
        return ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Nvl, "IFNULL");
    }

    @Override
    public void printSQLSelectStatement(DatabaseCall call, ExpressionSQLPrinter printer,
            SQLSelectStatement statement) {
        int max = 0;
        int firstRow = 0;
        ReadQuery query = statement.getQuery();
        if (query != null) {
            max = query.getMaxRows();
            firstRow = query.getFirstResult();
        }

        if (max <= 0 && firstRow <= 0) {
            // neither max nor firstRow is set
            super.printSQLSelectStatement(call, printer, statement);
            return;
        }
        if (max <= 0) {
            // if max row is not set use MAX_VALUE instead
            // this is done, because NewDB does not allow
            // OFFSET without LIMIT, and scrollable cursor is not supported
            // in order to support firstRows without MaxRows also MaxRow has to be set
            // this limits also the size of the result set in this case to Integer.MAX_VALUE rows
            query.setMaxRows(Integer.MAX_VALUE);
        }
        statement.setUseUniqueFieldAliases(true);
        call.setFields(statement.printSQL(printer));
        printer.printString(" LIMIT ");
        printer.printParameter(DatabaseCall.MAXROW_FIELD);
        printer.printString(" OFFSET ");
        printer.printParameter(DatabaseCall.FIRSTRESULT_FIELD);
        call.setIgnoreFirstRowSetting(true);
        call.setIgnoreMaxResultsSetting(true);
    }

    @Override
    public int computeMaxRowsForSQL(int firstResultIndex, int maxResults) {
        return maxResults - ((firstResultIndex >= 0) ? firstResultIndex : 0);
    }

    @Override
    public boolean shouldOptimizeDataConversion() {
        return true; // TODO is this needed? (seems to default to true)
    }

    private void addNonBindingOperator(ExpressionOperator operator) {
        operator.setIsBindingSupported(false);
        addOperator(operator);
    }

    @Override
    public boolean supportsNativeSequenceNumbers() {
        return true;
    }

    @Override
    public ValueReadQuery buildSelectQueryForSequenceObject(final String sequenceName, final Integer size) {
        return new ValueReadQuery("SELECT " + sequenceName + ".NEXTVAL FROM DUMMY");
    }

    @Override
    public boolean supportsGlobalTempTables() {
        return false;
    }

    @Override
    protected String getCreateTempTableSqlPrefix() {
        return "CREATE LOCAL TEMPORARY TABLE ";
    }

    @Override
    public DatabaseTable getTempTableForTable(DatabaseTable table) {
        return new DatabaseTable("#" + table.getName(), table.getTableQualifier(), table.shouldUseDelimiters(), getStartDelimiter(), getEndDelimiter());
    }

    @Override
    protected boolean shouldTempTableSpecifyPrimaryKeys() {
        return false;
    }

    @Override
    public int getMaxFieldNameSize() {
        return 120;
    }

    @Override
    public boolean supportsLocalTempTables() {
        return true;
    }

    @Override
    public boolean shouldAlwaysUseTempStorageForModifyAll() {
        return false;
    }

    @Override
    public boolean shouldBindLiterals() {
        return false;
    }

    @Override
    public boolean shouldPrintOuterJoinInWhereClause() {
        return false;
    }

    @Override
    public boolean shouldUseJDBCOuterJoinSyntax() {
        return false;
    }

    @Override
    public boolean supportsSequenceObjects() {
        return true;
    }

    @Override
    public boolean canBatchWriteWithOptimisticLocking(DatabaseCall call) {
        return true;
    }

    @Override
    public int executeBatch(Statement statement, boolean isStatementPrepared) throws SQLException {
        int[] updateResult = statement.executeBatch();
        if (isStatementPrepared) {
            int updateCount = 0;
            for (int count : updateResult) {
                if (count == Statement.SUCCESS_NO_INFO) {
                    count = 1;
                }
                updateCount += count;
            }
            return updateCount;
        } else {
            return updateResult.length;
        }
    }

    @Override
    public boolean supportsForeignKeyConstraints() {
        return true;
    }

    /**
     * Used for stored procedure creation: Prefix for INPUT parameters. Not required on most
     * platforms.
     */
    @Override
    public String getInputProcedureToken() {
        return "IN";
    }

    /**
     * This method is used to print the output parameter token when stored procedures are called
     */
    @Override
    public String getOutputProcedureToken() {
        return "OUT";
    }

    /**
     * Used for sp calls.
     */
    @Override
    public String getProcedureCallTail() {
        return "";
    }

    /**
     * INTERNAL: Should the variable name of a stored procedure call be printed as part of the
     * procedure call e.g. EXECUTE PROCEDURE MyStoredProc(myvariable = ?)
     */
    @Override
    public boolean shouldPrintStoredProcedureArgumentNameInCall() {
        return false;
    }

    @Override
    public boolean supportsStoredFunctions() {
        return false;
    }

    @Override
    protected void appendDate(Date date, Writer writer) throws IOException {
        writer.write("TO_DATE('");
        writer.write(Helper.printDate(date));
        writer.write("')");
    }

    @Override
    protected void appendTime(Time time, Writer writer) throws IOException {
        writer.write("TO_TIME('");
        writer.write(Helper.printTime(time));
        writer.write("')");
    }

    @Override
    protected void appendTimestamp(Timestamp timestamp, Writer writer) throws IOException {
        writer.write("TO_TIMESTAMP('");
        writer.write(Helper.printTimestamp(timestamp));
        writer.write("')");
    }

    @Override
    protected void appendCalendar(Calendar calendar, Writer writer) throws IOException {
        writer.write("TO_TIMESTAMP('");
        writer.write(Helper.printCalendar(calendar));
        writer.write("')");
    }

    @Override
    public void writeAddColumnClause(Writer writer, AbstractSession session, TableDefinition table, FieldDefinition field) throws IOException {
        writer.write("ADD (");
        field.appendDBString(writer, session, table);
        writer.write(")");
    }

    @Override
    public String getProcedureCallHeader() {
        return "CALL ";
    }
}
