/*
 * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2009, 2018 Markus Karg, 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:
// Markus Karg - initial contribution (bug 284657)
// SAP AG      - finalized implementation (bug 327778)
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.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.expressions.ListExpressionOperator;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.tools.schemaframework.FieldDefinition;

/**
 * <b>Database Platform for SAP MaxDB.</b>
 * <p>
 * <a href="http://wiki.eclipse.org/EclipseLink/Development/DatabasePlatform/MaxDBPlatform"><b>Wiki page</b></a>
 * <p>
 * <b>Usage</b>
 * <p>
 * The MaxDB platform is configured in the persistence.xml by the following property:
 * <p>
 * <code>&lt;property name="eclipselink.target-database" value="MaxDB"/&gt;</code>
 * <p>
 * Forward mapping with EclipseLink assumes that MaxDB is configured for unicode (in version 7.7, this is the default). Unicode mode also needs to be specified in the URL as follows:
 * <p>
 * <code>jdbc:sapdb://localhost/E32?unicode=yes</code>
 * <p>
 * <b>Tested with:</b>
 * <ul>
 * <li>DB: MaxDB, kernel 7.8.01 build 004-123-218-928</li>
 * <li>JDBC driver: MaxDB JDBC Driver, SAP AG, 7.6.06 Build 006-000-009-234 (Make-Version: 7.8.01 Build 003-123-215-703)</li>
 * </ul>
 *
 * <b>Limitations:</b>
 * <br>
 * <ul>
 * <li>The platform class must not be used with XA transactions - see bug 329773.</li>
 * <li>SetQueryTimeout or the hint "jakarta.persistence.query.timeout" do not work on MaxDB - see bug 326503.</li>
 * <li>The hint "jakarta.persistence.lock.timeout" has no effect with a positive value; a value of 0 is translated to NOWAIT.</li>
 * <li>The maximum width of an index is 1024 bytes on MaxDB. This also limits the size of a primary key. Moreover the primary key of join tables must not exceed this limit either. As it is composed of the primary key of the two tables that are joined, the combined width of the PKs of these two tables must not exceed this limit. See bug bug 326968.</li>
 * <li>VARCHAR [UNICODE] columns do not preserve trailing spaces - see bug 327435.</li>
 * <li>VARCHAR BYTE columns do not preserve trailing 0 bytes.</li>
 * <li>The hint "jakarta.persistence.lock.timeout=0" (NOWAIT) has no effect when atempting to pessimistically lock an entity with inheritance type JOINED - see bug 326799.</li>
 * <li>Pessimistic locking with lock scope EXTENDED should be used cautiously in the presence of foreign key constraints - see bug 327472.</li>

 * </ul>
 * <br>
 * @author Markus KARG (markus at headcrashing.eu)
 * @author afischbach
 * @author agoerler
 * @author Sabine Heider (sabine.heider at sap.com)
 * @author Konstantin Schwed (konstantin.schwed at sap.com)
 */
@SuppressWarnings("serial")
public final class MaxDBPlatform extends DatabasePlatform {

    private static final FieldTypeDefinition FIELD_TYPE_DEFINITION_CLOB = new FieldTypeDefinition("LONG UNICODE", false);

    private static final FieldTypeDefinition FIELD_TYPE_DEFINITION_BLOB = new FieldTypeDefinition("LONG BYTE", false);

    /**
     * Maximum length of type VARCHAR UNICODE
     *
     * (<a href="http://maxdb.sap.com/doc/7_8/45/33337d9faf2b34e10000000a1553f7/content.htm">link</a>)
     */
    private static final int MAX_VARCHAR_UNICODE_LENGTH = 4000; //

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

    @Override
    public String getSelectForUpdateString() {
        return " WITH LOCK EXCLUSIVE";
    }

    @Override
    public String getSelectForUpdateNoWaitString() {
        return " WITH LOCK (NOWAIT) EXCLUSIVE";
    }

    public MaxDBPlatform(){
        super();
        this.pingSQL = "SELECT 1 FROM DUAL";
    }

    @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 PRECISION", false));
        fieldTypeMapping.put(Short.class, new FieldTypeDefinition("SMALLINT", false));
        fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("INTEGER", false));
        fieldTypeMapping.put(Long.class, new FieldTypeDefinition("FIXED", 19));
        fieldTypeMapping.put(Float.class, new FieldTypeDefinition("FLOAT", false));
        fieldTypeMapping.put(Double.class, new FieldTypeDefinition("DOUBLE PRECISION", false));

        fieldTypeMapping.put(BigInteger.class, new FieldTypeDefinition("FIXED",19));
        fieldTypeMapping.put(BigDecimal.class, new FieldTypeDefinition("FIXED", 38));

        fieldTypeMapping.put(Character.class, new FieldTypeDefinition("CHAR", 1, "UNICODE"));
        fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("VARCHAR", 255, "UNICODE"));
        fieldTypeMapping.put(char[].class, new FieldTypeDefinition("VARCHAR", 255, "UNICODE"));
        fieldTypeMapping.put(String.class, new FieldTypeDefinition("VARCHAR", 255, "UNICODE"));

        fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("SMALLINT", false)); // can't be mapped to CHAR(1) BYTE as byte in java is signed
        fieldTypeMapping.put(Byte[].class, FIELD_TYPE_DEFINITION_BLOB);
        fieldTypeMapping.put(byte[].class, FIELD_TYPE_DEFINITION_BLOB);
        fieldTypeMapping.put(Blob.class, FIELD_TYPE_DEFINITION_BLOB);
        fieldTypeMapping.put(Clob.class, FIELD_TYPE_DEFINITION_CLOB);

        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
    public boolean supportsIndividualTableLocking() {
        return false;
    }

    @Override
    /**
     * EclipseLink does not support length dependent type mapping.
     * Map VARCHAR types with length > MAX_VARCHAR_UNICODE_LENGTH to LONG UNICODE (i.e clob); shorter types to VARCHAR (n) UNICODE
     * See also bugs 317597, 317448
     */
    protected void printFieldTypeSize(Writer writer, FieldDefinition field, FieldTypeDefinition fieldType) throws IOException {
        String typeName = fieldType.getName();
        if ("VARCHAR".equals(typeName) && "UNICODE".equals(fieldType.getTypesuffix())) {
            if (field.getSize() > MAX_VARCHAR_UNICODE_LENGTH) {
                fieldType = FIELD_TYPE_DEFINITION_CLOB;
            }
        }


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


    @Override
    protected void initializePlatformOperators() {
        super.initializePlatformOperators();
        this.addOperator(MaxDBPlatform.createConcatExpressionOperator());
        this.addOperator(MaxDBPlatform.createTrim2ExpressionOperator());
        this.addOperator(MaxDBPlatform.createToNumberOperator());
        this.addOperator(MaxDBPlatform.createNullifOperator());
        this.addOperator(MaxDBPlatform.createCoalesceOperator());
        this.addOperator(MaxDBPlatform.createTodayExpressionOperator());
        this.addOperator(MaxDBPlatform.createCurrentDateExpressionOperator());
        this.addOperator(MaxDBPlatform.createCurrentTimeExpressionOperator());
        this.addNonBindingOperator(MaxDBPlatform.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, "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, "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, "TIME");
    }

    private static ExpressionOperator createTrim2ExpressionOperator() {
        return ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Trim2, "TRIM");
    }

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

    /* see bug 316774 */
    private static ExpressionOperator createCoalesceOperator() {
        ListExpressionOperator operator = (ListExpressionOperator) ExpressionOperator.coalesce();
        operator.setStartString("VALUE(");
        operator.setSelector(ExpressionOperator.Coalesce);
        return operator;
    }

    private static ExpressionOperator createToNumberOperator() {
        return ExpressionOperator.simpleFunction(ExpressionOperator.ToNumber, "NUM");
    }

    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;
    }

    @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 DUAL");
    }

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

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

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

    @Override
    public DatabaseTable getTempTableForTable(final DatabaseTable table) {
        return new DatabaseTable("$" + table.getName(), "TEMP");
    }

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

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

    @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 supportsStoredFunctions() {
        return true;
    }

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

}
