/*
 * Copyright (c) 1998, 2020 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 from Oracle TopLink
package org.eclipse.persistence.internal.expressions;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import java.util.Collection;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.helper.DatabaseField;

/**
 * @author Guy Pelletier
 * @since TOPLink/Java 1.0
 */
public class SQLUpdateAllStatement extends SQLModifyStatement {
    protected HashMap m_updateClauses;
    protected HashMap databaseFieldsToTableAliases;

    protected SQLCall selectCallForExist;
    protected String tableAliasInSelectCallForExist;
    protected Collection primaryKeyFields;
    protected boolean shouldExtractWhereClauseFromSelectCallForExist;

    public void setSelectCallForExist(SQLCall selectCallForExist) {
        this.selectCallForExist = selectCallForExist;
    }
    public SQLCall getSelectCallForExist() {
        return selectCallForExist;
    }
    public void setTableAliasInSelectCallForExist(String tableAliasInSelectCallForExist) {
        this.tableAliasInSelectCallForExist = tableAliasInSelectCallForExist;
    }
    public String getTableAliasInSelectCallForExist() {
        return tableAliasInSelectCallForExist;
    }
    public void setPrimaryKeyFieldsForAutoJoin(Collection primaryKeyFields) {
        this.primaryKeyFields = primaryKeyFields;
    }
    public Collection getPrimaryKeyFieldsForAutoJoin() {
        return primaryKeyFields;
    }
    public void setUpdateClauses(HashMap updateClauses) {
        m_updateClauses = updateClauses;
    }
    public HashMap getUpdateClauses() {
        return m_updateClauses;
    }
    public void setDatabaseFieldsToTableAliases(HashMap databaseFieldsToTableAliases) {
        this.databaseFieldsToTableAliases = databaseFieldsToTableAliases;
    }
    public HashMap getDatabaseFieldsToTableAliases() {
        return databaseFieldsToTableAliases;
    }
    public void setShouldExtractWhereClauseFromSelectCallForExist(boolean shouldExtractWhereClauseFromSelectCallForExist) {
        this.shouldExtractWhereClauseFromSelectCallForExist = shouldExtractWhereClauseFromSelectCallForExist;
    }
    public boolean shouldExtractWhereClauseFromSelectCallForExist() {
        return shouldExtractWhereClauseFromSelectCallForExist;
    }


    /**
     * Append the string containing the SQL insert string for the given table.
     */
    @Override
    public DatabaseCall buildCall(AbstractSession session) {
        SQLCall call = buildSimple(session);
        if(selectCallForExist == null) {
            return call;
        }
        Writer writer = new CharArrayWriter(100);
        try {
            writer.write(call.getSQLString());

            if(selectCallForExist != null) {
                if(shouldExtractWhereClauseFromSelectCallForExist) {
                    // Should get here only in case selectCallForExist doesn't have aliases and
                    // targets the same table as the statement.
                    // Instead of making selectCallForExist part of " WHERE EXIST("
                    // just extract its where clause.
                    // Example: selectCallForExist.sqlString:
                    // "SELECT PROJ_ID FROM PROJECT WHERE (LEADER_ID IS NULL)
                    writeWhere(writer, selectCallForExist, call);
                    // The result is:
                    // "WHERE (LEADER_ID IS NULL)"
                } else {
                    writer.write(" WHERE EXISTS(");
                    // EXIST Example: selectCall.sqlString:
                    // "SELECT t0.EMP_ID FROM EMPLOYEE t0, SALARY t1 WHERE (((t0.F_NAME LIKE 'a') AND (t1.SALARY = 0)) AND (t1.EMP_ID = t0.EMP_ID))"
                    writeSelect(writer, selectCallForExist, tableAliasInSelectCallForExist, call, session.getPlatform());
                    // closing bracket for EXISTS
                    writer.write(")");
                }
                // Bug 301888 - DB2: UpdateAll/DeleteAll using WHERE EXIST fail.
                // If selectCallForExist has been explicitly set to not use binding then call should be set the same way.
                if(selectCallForExist.isUsesBindingSet() && !selectCallForExist.usesBinding(session)) {
                    call.setUsesBinding(false);
                }
            }

            call.setSQLString(writer.toString());

        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }

        return call;
    }

    protected SQLCall buildSimple(AbstractSession session) {
        SQLCall call = new SQLCall();
        call.returnNothing();
        Writer writer = new CharArrayWriter(100);
        ExpressionSQLPrinter printer = new ExpressionSQLPrinter(session, getTranslationRow(), call, false, getBuilder());
        printer.setWriter(writer);

        try {
            // UPDATE //
            writer.write("UPDATE ");

            // HINT STRING //
            if (getHintString() != null) {
                writer.write(getHintString());
                writer.write(" ");
            }

            writer.write(getTable().getQualifiedNameDelimited(session.getPlatform()));

            // SET CLAUSE //
            writer.write(" SET ");

            Iterator i = m_updateClauses.keySet().iterator();
            boolean commaNeeded = false;

            while (i.hasNext()) {
                if (commaNeeded) {
                    writer.write(", ");
                }

                DatabaseField field = (DatabaseField)i.next();
                Object value = m_updateClauses.get(field);

                writer.write(field.getNameDelimited(session.getPlatform()));
                writer.write(" = ");
                if(value instanceof Expression) {
                    printer.printExpression((Expression)value);
                } else {
                    // must be SQLCall
                    SQLCall selCall = (SQLCall)value;
                    String tableAlias = (String)getDatabaseFieldsToTableAliases().get(field);
                    // should be SQLCall select
                    writer.write("(");
                    writeSelect(writer, selCall, tableAlias, call, session.getPlatform());
                    writer.write(")");
                }

                commaNeeded = true;
            }

            // WHERE CLAUSE //
            if (getWhereClause() != null) {
                writer.write(" WHERE ");
                printer.printExpression(getWhereClause());
            }

            call.setSQLString(writer.toString());
            return call;
        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }
    }

    protected void writeSelect(Writer writer, SQLCall selectCall, String tableAliasInSelectCall, SQLCall call, DatasourcePlatform platform) throws IOException {
        String str = selectCall.getSQLString();
        writer.write(str);

        boolean hasWhereClause = str.toUpperCase().indexOf(" WHERE ") >= 0;

        // Auto join
        // Example: AND t0.EMP_ID = EMP_ID
        Iterator it = getPrimaryKeyFieldsForAutoJoin().iterator();
        while(it.hasNext()) {
            if(!hasWhereClause) {
            // there is no where clause - should print WHERE
                writer.write(" WHERE ");
                hasWhereClause = true;
            } else {
                writer.write(" AND ");
            }
            String fieldName = ((DatabaseField)it.next()).getNameDelimited(platform);
            if(tableAliasInSelectCall != null) {
                writer.write(tableAliasInSelectCall);
                writer.write('.');
            }
            writer.write(fieldName);
            writer.write(" = ");
            writer.write(table.getQualifiedNameDelimited(platform));
            writer.write('.');
            writer.write(fieldName);
        }

        call.getParameters().addAll(selectCall.getParameters());
        call.getParameterTypes().addAll(selectCall.getParameterTypes());
    }

    protected boolean writeWhere(Writer writer, SQLCall selectCall, SQLCall call) throws IOException {
        String selectStr = selectCallForExist.getSQLString();

        int index = selectStr.toUpperCase().indexOf(" WHERE ");
        if(index < 0) {
            // no where clause - nothing to do
            return false;
        }

        // print the where clause
        String str = selectStr.substring(index);
        writer.write(str);

        // add parameters
        call.getParameters().addAll(selectCall.getParameters());
        call.getParameterTypes().addAll(selectCall.getParameterTypes());

        return true;
    }
}
