/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. 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
//     Markus KARG - Added methods allowing to support stored procedure creation on SQLAnywherePlatform.
package org.eclipse.persistence.tools.schemaframework;

import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Vector;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * <b>Purpose</b>: Allow a semi-generic way of creating stored procedures.
 */
public class StoredProcedureDefinition extends DatabaseObjectDefinition {
    protected List<FieldDefinition> variables;
    protected List<String> statements;
    protected List<FieldDefinition> arguments;
    protected List<Integer> argumentTypes;
    protected static final Integer IN = 1;
    protected static final Integer OUT = 2;
    protected static final Integer INOUT = 3;

    public StoredProcedureDefinition() {
        this.statements = new Vector<>();
        this.variables = new Vector<>();
        this.arguments = new Vector<>();
        this.argumentTypes = new Vector<>();
    }

    /**
     * The arguments are the names of the parameters to the procedure.
     */
    public void addArgument(String argumentName, Class type) {
        addArgument(new FieldDefinition(argumentName, type));
    }

    /**
     * The arguments are the names of the parameters to the procedure.
     */
    public void addArgument(String argumentName, Class type, int size) {
        addArgument(new FieldDefinition(argumentName, type, size));
    }

    /**
     * The arguments are the names of the parameters to the procedure.
     */
    public void addArgument(String argumentName, String typeName) {
        addArgument(new FieldDefinition(argumentName, typeName));
    }

    /**
     * The arguments are the names of the parameters to the procedure.
     */
    public void addArgument(FieldDefinition argument) {
        getArguments().add(argument);
        getArgumentTypes().add(IN);
    }

    /**
     * The output arguments are used to get values back from the proc.
     */
    public void addInOutputArgument(String argumentName, Class type) {
        addInOutputArgument(new FieldDefinition(argumentName, type));
    }

    /**
     * The output arguments are used to get values back from the proc, such as cursors.
     */
    public void addInOutputArgument(FieldDefinition argument) {
        getArguments().add(argument);
        getArgumentTypes().add(INOUT);
    }

    /**
     * The output arguments are used to get values back from the proc.
     */
    public void addOutputArgument(String argumentName, Class type) {
        addOutputArgument(new FieldDefinition(argumentName, type));
    }

    /**
     * The output arguments are used to get values back from the proc.
     */
    public void addOutputArgument(String argumentName, Class type, int size) {
        addOutputArgument(new FieldDefinition(argumentName, type, size));
    }

    /**
     * The output arguments are used to get values back from the proc, such as cursors.
     */
    public void addOutputArgument(String argumentName, String typeName) {
        addOutputArgument(new FieldDefinition(argumentName, typeName));
    }

    /**
     * The output arguments are used to get values back from the proc, such as cursors.
     */
    public void addOutputArgument(FieldDefinition argument) {
        getArguments().add(argument);
        getArgumentTypes().add(OUT);
    }

    /**
     * The statements are the SQL lines of code in procedure.
     */
    public void addStatement(String statement) {
        getStatements().add(statement);
    }

    /**
     * The variables are the names of the declared variables used in the procedure.
     */
    public void addVariable(String variableName, String typeName) {
        this.addVariable(new FieldDefinition(variableName, typeName));
    }

    /**
     * The variables are the names of the declared variables used in the procedure.
     */
    public void addVariable(FieldDefinition variable) {
        getVariables().add(variable);
    }

    /**
     * INTERNAL: Return the create table statement.
     */
    @Override
    public Writer buildCreationWriter(AbstractSession session, Writer writer) throws ValidationException {
        try {
            DatabasePlatform platform = session.getPlatform();
            writer.write(getCreationHeader() + getFullName());
            if (getArguments().size() > getFirstArgumentIndex() || platform.requiresProcedureBrackets()) {
                writer.write(" (");
            }
            writer.write("\n");
            for (int i = getFirstArgumentIndex(); i < getArguments().size(); i++) {
                writer.write("\t");
                FieldDefinition argument = getArguments().get(i);
                Integer argumentType = getArgumentTypes().get(i);
                if (argumentType == IN) {
                    printArgument(argument, writer, session);
                } else if (argumentType == OUT) {
                    printOutputArgument(argument, writer, session);
                } else if (argumentType == INOUT) {
                    printInOutputArgument(argument, writer, session);
                }
                if (i < (getArguments().size() - 1)) {
                    writer.write(",\n");
                }
            }
            if (getArguments().size() > getFirstArgumentIndex() || platform.requiresProcedureBrackets()) {
                writer.write(")");
            }

            printReturn(writer, session);
            writer.write(platform.getProcedureAsString());
            writer.write("\n");

            writer.write(platform.getProcedureOptionList());
            writer.write("\n");

            if (platform.shouldPrintStoredProcedureVariablesAfterBeginString()) {
                writer.write(platform.getProcedureBeginString());
                writer.write("\n");
            }

            if (!getVariables().isEmpty()) {
                writer.write("DECLARE\n");
            }

            for (FieldDefinition field: getVariables()) {
                writer.write("\t");
                writer.write(field.getName());
                writer.write(" ");
                writer.write(field.getTypeName());
                writer.write(platform.getBatchDelimiterString());
                writer.write("\n");
            }

            if (!platform.shouldPrintStoredProcedureVariablesAfterBeginString()) {
                writer.write(platform.getProcedureBeginString());
                writer.write("\n");
            }

            for (String statement: getStatements()) {
                writer.write(statement);
                writer.write(platform.getBatchDelimiterString());
                writer.write("\n");
            }
            writer.write(platform.getProcedureEndString());
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
        return writer;
    }

    /**
     * INTERNAL: Return the drop table statement.
     */
    @Override
    public Writer buildDeletionWriter(AbstractSession session, Writer writer) throws ValidationException {
        try {
            writer.write(getDeletionHeader() + getFullName());
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
        return writer;
    }

    /**
     * The arguments are the names of the parameters to the procedure.
     */
    public List<FieldDefinition> getArguments() {
        return arguments;
    }

    /**
         *
         */
    public String getCreationHeader() {
        return "CREATE PROCEDURE ";
    }

    /**
         *
         */
    public String getDeletionHeader() {
        return "DROP PROCEDURE ";
    }

    /**
         *
         */
    public int getFirstArgumentIndex() {
        return 0;
    }

    /**
         *
         */
    public List<Integer> getArgumentTypes() {
        return argumentTypes;
    }

    /**
     * The statements are the SQL lines of code in procedure.
     */
    public List<String> getStatements() {
        return statements;
    }

    /**
     * The variables are the names of the declared variables used in the procedure.
     */
    public List<FieldDefinition> getVariables() {
        return variables;
    }

    /**
     * Print the argument and its type.
     * @param argument Stored procedure argument.
     * @param writer   Target writer where to write argument string.
     * @param session  Current session context.
     * @throws IOException When any IO problem occurs.
     */
    protected void printArgument(final FieldDefinition argument, final Writer writer,
            final AbstractSession session) throws IOException {
        final DatabasePlatform platform = session.getPlatform();
        final FieldTypeDefinition fieldType
                = getFieldTypeDefinition(session, argument.type, argument.typeName);

        writer.write(platform.getProcedureArgumentString());

        if (platform.shouldPrintInputTokenAtStart()) {
            writer.write(" ");
            writer.write(platform.getInputProcedureToken());
            writer.write(" ");
        }

        writer.write(argument.name);
        writer.write(" ");
        writer.write(fieldType.getName());

        if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
                && ((argument.size != 0) || (fieldType.isSizeRequired()))) {
            writer.write("(");
            if (argument.size == 0) {
                writer.write(Integer.toString(fieldType.getDefaultSize()));
            } else {
                writer.write(Integer.toString(argument.size));
            }
            if (argument.subSize != 0) {
                writer.write(",");
                writer.write(Integer.toString(argument.subSize));
            } else if (fieldType.getDefaultSubSize() != 0) {
                writer.write(",");
                writer.write(Integer.toString(fieldType.getDefaultSubSize()));
            }
            writer.write(")");
        }
    }

    /**
     * Print the argument and its type.
     * @param argument Stored procedure argument.
     * @param writer   Target writer where to write argument string.
     * @param session  Current session context.
     * @throws ValidationException When invalid or inconsistent data were found.
     */
    protected void printInOutputArgument(final FieldDefinition argument, final Writer writer,
            final AbstractSession session) throws ValidationException {
        try {
            final DatabasePlatform platform = session.getPlatform();
            final FieldTypeDefinition fieldType
                    = getFieldTypeDefinition(session, argument.type, argument.typeName);

            writer.write(platform.getProcedureArgumentString());

            if (platform.shouldPrintOutputTokenAtStart()) {
                writer.write(" ");
                writer.write(platform.getCreationInOutputProcedureToken());
                writer.write(" ");
            }
            writer.write(argument.name);
            if ((!platform.shouldPrintOutputTokenAtStart()) && platform.shouldPrintOutputTokenBeforeType()) {
                writer.write(" ");
                writer.write(platform.getCreationInOutputProcedureToken());
            }
            writer.write(" ");
            writer.write(fieldType.getName());
            if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
                    && ((argument.size != 0) || (fieldType.isSizeRequired()))) {
                writer.write("(");
                if (argument.size == 0) {
                    writer.write(Integer.toString(fieldType.getDefaultSize()));
                } else {
                    writer.write(Integer.toString(argument.size));
                }
                if (argument.subSize != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(argument.subSize));
                } else if (fieldType.getDefaultSubSize() != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(fieldType.getDefaultSubSize()));
                }
                writer.write(")");
            }
            if ((!platform.shouldPrintOutputTokenAtStart()) && (!platform.shouldPrintOutputTokenBeforeType())) {
                writer.write(" ");
                writer.write(platform.getCreationInOutputProcedureToken());
            }
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * Print the argument and its type.
     * @param argument Stored procedure argument.
     * @param writer   Target writer where to write argument string.
     * @param session  Current session context.
     * @throws ValidationException When invalid or inconsistent data were found.
     */
    protected void printOutputArgument(final FieldDefinition argument, final Writer writer,
            final AbstractSession session) throws ValidationException {
        try {
            final DatabasePlatform platform = session.getPlatform();
            final FieldTypeDefinition fieldType
                    = getFieldTypeDefinition(session, argument.type, argument.typeName);

            writer.write(platform.getProcedureArgumentString());

            if (platform.shouldPrintOutputTokenAtStart()) {
                writer.write(" ");
                writer.write(platform.getCreationOutputProcedureToken());
                writer.write(" ");
            }
            writer.write(argument.name);
            if ((!platform.shouldPrintOutputTokenAtStart()) && platform.shouldPrintOutputTokenBeforeType()) {
                writer.write(" ");
                writer.write(platform.getCreationOutputProcedureToken());
            }
            writer.write(" ");
            writer.write(fieldType.getName());
            if (fieldType.isSizeAllowed() && platform.allowsSizeInProcedureArguments()
                    && ((argument.size != 0) || (fieldType.isSizeRequired()))) {
                writer.write("(");
                if (argument.size == 0) {
                    writer.write(Integer.toString(fieldType.getDefaultSize()));
                } else {
                    writer.write(Integer.toString(argument.size));
                }
                if (argument.subSize != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(argument.subSize));
                } else if (fieldType.getDefaultSubSize() != 0) {
                    writer.write(",");
                    writer.write(Integer.toString(fieldType.getDefaultSubSize()));
                }
                writer.write(")");
            }
            if ((!platform.shouldPrintOutputTokenAtStart()) && !platform.shouldPrintOutputTokenBeforeType()) {
                writer.write(" ");
                writer.write(platform.getCreationOutputProcedureToken());
            }
        } catch (IOException ioException) {
            throw ValidationException.fileError(ioException);
        }
    }

    /**
     * Prints return for stored function, nothing to do for stored procedure
     */
    protected void printReturn(Writer writer, AbstractSession session) throws ValidationException {
    }

    /**
     * The arguments are the field defs of the parameters names and types to the procedure.
     */
    public void setArguments(List<FieldDefinition> arguments) {
        this.arguments = arguments;
    }

    /**
     * The statements are the SQL lines of code in procedure.
     */
    public void setStatements(List<String> statements) {
        this.statements = statements;
    }

    /**
     * The variables are the field defs of the declared variables used in the procedure.
     */
    public void setVariables(List<FieldDefinition> variables) {
        this.variables = variables;
    }
}
