/*
 * 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:
//     Mike Norman - May 01 2008, created DBWS tools package

package org.eclipse.persistence.tools.dbws;

// javase imports
import java.util.ArrayList;
import java.util.List;

// EclipseLink imports
import org.eclipse.persistence.internal.helper.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;

public class ProcedureOperationModel extends ModelWithBuildSql {

    protected String catalogPattern;
    protected String schemaPattern;
    protected String procedurePattern;
    //cache resolved DatabaseType's
    transient protected List<ProcedureType> dbStoredProcedures = new ArrayList<ProcedureType>();

    //TODO - do we really need any of these?
    protected int overload; // Oracle-specific
    protected boolean isAdvancedJDBC = false;
    protected List<DatabaseType[]> argumentTypes = null;
    protected DatabaseType dbStoredFunctionReturnType = null;
    protected boolean hasComplexArguments = false;

    public ProcedureOperationModel() {
        super();
    }

    @Override
    public boolean isProcedureOperation() {
        return true;
    }
    public boolean isPLSQLProcedureOperation() {
        return false;
    }

    public String getCatalogPattern() {
        return catalogPattern;
    }
    public void setCatalogPattern(String catalogPattern) {
        if ("null".equalsIgnoreCase(catalogPattern)) {
            this.catalogPattern = null;
        }
        else {
            this.catalogPattern = catalogPattern;
        }
    }

    public String getSchemaPattern() {
        return schemaPattern;
    }
    public void setSchemaPattern(String schemaPattern) {
        if ("null".equalsIgnoreCase(schemaPattern)) {
            this.schemaPattern = null;
        }
        else {
            this.schemaPattern = schemaPattern;
        }
    }

    public String getProcedurePattern() {
        return procedurePattern;
    }
    public void setProcedurePattern(String procedurePattern) {
        this.procedurePattern = procedurePattern;
    }

    public List<ProcedureType> getDbStoredProcedures() {
        return dbStoredProcedures;
    }
    public void setDbStoredProcedures(List<ProcedureType> dbStoredProcedures) {
        this.dbStoredProcedures = dbStoredProcedures;
    }

    public int getOverload() {
        return overload;
    }
    public void setOverload(int overload) {
        this.overload = overload;
    }

    public boolean isAdvancedJDBCProcedureOperation() {
        return isAdvancedJDBC;
    }
    public void setIsAdvancedJDBCProcedureOperation(boolean isAdvancedJDBC) {
        this.isAdvancedJDBC = isAdvancedJDBC;
    }

    @Override
    public void buildOperation(DBWSBuilder builder) {
        super.buildOperation(builder);
        builder.getBuilderHelper().buildProcedureOperation(this);
    }

    /**
     * Indicates if this ProcedureOperationModel has types set for its
     * stored procedure arguments, i.e. argumentTypes is non-null.
     *
     * @return true if this ProcedureOperationModel has types set for
     *         its stored procedure arguments, false otherwise
     */
    public boolean hasArgumentTypes() {
        return argumentTypes != null;
    }

    /**
     * Return the List of DatabaseType[] entries for this ProcedureOperationModel
     * instance's stored procedure arguments, or null if not set.   It is assumed
     * that each entry in the List corresponds to a  stored procedure at the same
     * index in the dbStoredProcedures List. It is also assumed the each entry in
     * a given DatabaseType[] corresponds to an argument in the associated stored
     * procedure at the same index.
     *
     * @return List of DatabaseType[] entries for this ProcedureOperationModel
     *         instance's stored procedure arguments, or null if not set
     */
    public List<DatabaseType[]> getArgumentTypes() {
        return argumentTypes;
    }

    /**
     * Add to the List of DatabaseType[] entries  for  this  ProcedureOperationModel
     * instance's stored procedures.       It is assumed that each entry in the List
     * corresponds to a stored procedure at the same index in the dbStoredProcedures
     * List. It is also assumed the each entry in a given DatabaseType[] corresponds
     * to an argument in the associated stored procedure at the same index.
     *
     */
    public void addArgumentTypes(DatabaseType[] dbTypes) {
        if (argumentTypes == null) {
            argumentTypes = new ArrayList<DatabaseType[]>();
        }
        argumentTypes.add(dbTypes);
    }

    /**
     * Set  the  List of DatabaseType[]  entries  for  this  ProcedureOperationModel
     * instance's stored procedures.       It is assumed that each entry in the List
     * corresponds to a stored procedure at the same index in the dbStoredProcedures
     * List. It is also assumed the each entry in a given DatabaseType[] corresponds
     * to an argument in the associated stored procedure at the same index.
     *
     */
    public void setArgumentTypes(List<DatabaseType[]> argumentTypes) {
        this.argumentTypes = argumentTypes;
    }

    /**
     * Get the DatabaseType of the stored function's return argument.
     *
     * @return the stored function's return type
     */
    public DatabaseType getDbStoredFunctionReturnType() {
        return dbStoredFunctionReturnType;
    }

    /**
     * Set the DatabaseType of the stored function's return argument.
     *
     */
    public void setDbStoredFunctionReturnType(DatabaseType dbStoredFunctionReturnType) {
        this.dbStoredFunctionReturnType = dbStoredFunctionReturnType;
    }

    /**
     * Indicates if this ProcedureOperationModel contains advanced Oracle
     * and/or complex PL/SQL arguments.
     */
    public boolean hasComplexArguments() {
        return hasComplexArguments;
    }

    /**
     * Sets the boolean that indicates if this ProcedureOperationModel
     * contains advanced Oracle and/or complex PL/SQL arguments.
     */
    public void setHasComplexArguments(boolean hasComplexArguments) {
        this.hasComplexArguments = hasComplexArguments;
    }
}
