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

import java.util.*;

import org.eclipse.persistence.tools.schemaframework.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;

/**
 * This stored procedure generator is meant to generate INSERT and UPDATE
 * procedures that return values, but currently only generates
 * procedures that just perform the INSERT/UPDATE, so is not currently used.
 * It will hopefully be finished at some point...
 */
public class StoredProcedureGeneratorForAdapter extends StoredProcedureGenerator {

    public StoredProcedureGeneratorForAdapter(SchemaManager schemaMngr) {
        super(schemaMngr);
        insertStoredProcedures = new Hashtable<>();
        updateStoredProcedures = new Hashtable<>();
        substituteName = new Hashtable<>();
    }

    protected Map<ClassDescriptor, StoredProcedureDefinition> insertStoredProcedures;
    protected Map<ClassDescriptor, StoredProcedureDefinition> updateStoredProcedures;
    protected Map<StoredProcedureDefinition, Map<String, String>> substituteName;
    protected boolean useTableNames;

    public boolean usesTableNames() {
        return useTableNames;
    }

    public void setUseTableNames(boolean useTableNames) {
        this.useTableNames = useTableNames;
    }

    /**
     * PUBLIC:
     * Inspired by StoredProcedureGenerator.generateStoredProcedures though
     * uses another attribute (insertStoredProcedures) and doesn't write definitions
     */
    public void generateInsertStoredProceduresDefinitionsForProject(Project project) {
        verifyProject(project);
        Map<Class<?>, ClassDescriptor> descrpts = project.getDescriptors();
        Iterator<Class<?>> iterator = descrpts.keySet().iterator();
        ClassDescriptor desc;
        while (iterator.hasNext()) {
            desc = descrpts.get(iterator.next());
            if (desc.isDescriptorForInterface() || desc.isAggregateDescriptor()) {
                continue;
            }
            if (!desc.getQueryManager().hasInsertQuery()) {
                InsertObjectQuery insertQuery = new InsertObjectQuery();
                insertQuery.setModifyRow(desc.getObjectBuilder().buildTemplateInsertRow(getSession()));
                desc.getQueryManager().setInsertQuery(insertQuery);
            }
            StoredProcedureDefinition definition = generateStoredProcedureDefinition(desc, desc.getQueryManager().getInsertQuery(), "INS_");
            insertStoredProcedures.put(desc, definition);
        }
    }

    public void generateUpdateStoredProceduresDefinitionsForProject(Project project) {
        verifyProject(project);
        Map<Class<?>, ClassDescriptor> descrpts = project.getDescriptors();
        Iterator<Class<?>> iterator = descrpts.keySet().iterator();
        ClassDescriptor desc;
        while (iterator.hasNext()) {
            desc = descrpts.get(iterator.next());
            if (desc.isDescriptorForInterface() || desc.isAggregateDescriptor()) {
                continue;
            }
            if (!desc.getQueryManager().hasUpdateQuery()) {
                UpdateObjectQuery updateQuery = new UpdateObjectQuery();
                updateQuery.setModifyRow(desc.getObjectBuilder().buildTemplateUpdateRow(getSession()));
                if (updateQuery.getModifyRow().size() > 0) {
                    desc.getQueryManager().setUpdateQuery(updateQuery);
                }
            }
            if (desc.getQueryManager().getUpdateQuery() != null) {
                StoredProcedureDefinition definition = generateStoredProcedureDefinition(desc, desc.getQueryManager().getUpdateQuery(), "UPD_");
                updateStoredProcedures.put(desc, definition);
            }
        }
    }

    protected StoredProcedureDefinition generateStoredProcedureDefinition(ClassDescriptor desc, DatabaseQuery query, String namePrefix) {
        List<DatabaseField> fields = desc.getFields();
        Map<String, String> namesNewToNames = null;
        if (shouldCapitalizeNames()) {
            namesNewToNames = new Hashtable<>();
            fields = capitalize(fields, namesNewToNames);
        }
        StoredProcedureDefinition definition = generateObjectStoredProcedure(query, fields, namePrefix);
        if (namesNewToNames != null && !namesNewToNames.isEmpty()) {
            substituteName.put(definition, namesNewToNames);
        }
        return definition;
    }

    public void generateStoredProceduresDefinitionsForProject(Project project) {
        generateInsertStoredProceduresDefinitionsForProject(project);
        generateUpdateStoredProceduresDefinitionsForProject(project);
    }

    /**
     * PUBLIC:
     */
    public void writeInsertStoredProcedures() {
        for (StoredProcedureDefinition definition : insertStoredProcedures.values()) {
            writeDefinition(definition);
        }
    }

    public void writeUpdateStoredProcedures() {
        for (StoredProcedureDefinition definition : updateStoredProcedures.values()) {
            writeDefinition(definition);
        }
    }

    public void writeStoredProcedures() {
        writeInsertStoredProcedures();
        writeUpdateStoredProcedures();
    }

    /**
     * INTERNAL:
     * The base class doesn't allow optimistic locking in getSession().getProject() -
     * override this restriction.
     */
    @Override
    protected void verify() throws org.eclipse.persistence.exceptions.ValidationException {
    }

    /**
     * INTERNAL:
     * The base class doesn't allow optimistic locking in the project.
     */
    protected void verifyProject(Project project) {
        if (project.usesOptimisticLocking()) {
            throw org.eclipse.persistence.exceptions.ValidationException.optimisticLockingNotSupportedWithStoredProcedureGeneration();
        }
    }

    /**
     * PUBLIC:
     * Amends descriptors with stored procedures
     */
    public void amendDescriptorsInsertQuery() {
        for (Map.Entry<ClassDescriptor, StoredProcedureDefinition> entry : insertStoredProcedures.entrySet()) {
            InsertObjectQuery insertQuery = new InsertObjectQuery();
            defineQuery(insertQuery, entry.getValue());
            entry.getKey().getQueryManager().setInsertQuery(insertQuery);
        }
    }

    public void amendDescriptorsUpdateQuery() {
        for (Map.Entry<ClassDescriptor, StoredProcedureDefinition> entry : updateStoredProcedures.entrySet()) {
            UpdateObjectQuery updateQuery = new UpdateObjectQuery();
            defineQuery(updateQuery, entry.getValue());
            entry.getKey().getQueryManager().setUpdateQuery(updateQuery);
        }
    }

    public void defineQuery(DatabaseQuery query, StoredProcedureDefinition definition) {
        Hashtable namesNewToNames = (Hashtable)substituteName.get(definition);
        query.setShouldBindAllParameters(true);
        StoredProcedureCall call = new StoredProcedureCall();
        call.setProcedureName(definition.getName());
        for (int i = 0; i < definition.getArguments().size(); i++) {
            FieldDefinition fieldDefinition = definition.getArguments().get(i);
            String procedureParameterName = fieldDefinition.getName();
            String fieldName = getFieldName(fieldDefinition.getName());
            String argumentFieldName = fieldName;
            if (namesNewToNames != null) {
                String fieldNameOriginal = (String)namesNewToNames.get(fieldName);
                if (fieldNameOriginal != null) {
                    argumentFieldName = fieldNameOriginal;
                }
            }
            call.addNamedArgument(procedureParameterName, argumentFieldName);
        }
        query.setCall(call);
    }

    public void amendDescriptors() {
        amendDescriptorsInsertQuery();
        amendDescriptorsUpdateQuery();
    }

    // Need for capitalization is caused by bug3172139:
    // ORACLE CONNECTION METADATA.GETCOLUMNS FAILS IF PASSED LOWER-CASE NAMES
    // In case the bug is fixed, there would be no need for returning newFields.
    // However namesCapitalizedToNames still will be needed, because the DatabaseField's
    // name to be used as a parameter for StoredProcedureCall is extracted from
    // storedProcedureDefinition - and there it is always the same as in database.
    @SuppressWarnings({"unchecked"})
    protected List<DatabaseField> capitalize(List<DatabaseField> fields, Map<String, String> namesCapitalizedToNames) {
        // Can't change names of descriptor's fields, create a new Vector.
        List<DatabaseField> newFields = null;
        for (int i = 0; i < fields.size(); i++) {
            DatabaseField field = fields.get(i);
            String fieldNameUpper = field.getName().toUpperCase();
            String tableNameUpper = field.getTableName().toUpperCase();
            if (!fieldNameUpper.equals(field.getName()) || !tableNameUpper.equals(field.getTableName())) {
                DatabaseField newField = new DatabaseField(fieldNameUpper, tableNameUpper);
                newField.setType(field.getType());
                if (newFields == null) {
                    newFields = (List<DatabaseField>) ((Vector<DatabaseField>)fields).clone();
                }
                newFields.set(i, newField);
                namesCapitalizedToNames.put(fieldNameUpper, field.getName());
            }
        }
        if (newFields == null) {
            return fields;
        } else {
            return newFields;
        }
    }

    protected boolean shouldCapitalizeNames() {
        return getSession().getPlatform().isOracle();
    }

    protected String shortClassName(String originalClassName, int numberOfPackagesToIncludeIntoShortName) {
        int nLastIndex = originalClassName.length() - 1;
        for (int i = 0; i <= numberOfPackagesToIncludeIntoShortName && nLastIndex > 0; i++) {
            nLastIndex = originalClassName.lastIndexOf('.', nLastIndex - 1);
        }
        if (nLastIndex < 0 || nLastIndex == originalClassName.length() - 1) {
            return new String(originalClassName);
        } else {
            return originalClassName.substring(nLastIndex + 1);
        }
    }

    protected StoredProcedureDefinition generateObjectStoredProcedure(DatabaseQuery query, List<DatabaseField> fields, String namePrefix) {
        String namePrefixToUse = namePrefix;
        String className = Helper.getShortClassName(query.getDescriptor().getJavaClass());
        if (useTableNames) {
            String tableName = query.getDescriptor().getTableName();
            if (!compareNames(className, tableName)) {
                namePrefixToUse = namePrefix + tableName + "_";
            }
        }
        return generateStoredProcedure(query, fields, getPrefix() + namePrefixToUse + className);
    }

    protected boolean compareNames(String name1, String name2) {
        if (shouldCapitalizeNames()) {
            return name1.equalsIgnoreCase(name2);
        } else {
            return name1.equals(name2);
        }
    }
}
