/*
 * Copyright (c) 1998, 2019 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
package org.eclipse.persistence.internal.databaseaccess;

import java.sql.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;

public class OutputParameterForCallableStatement extends BindCallCustomParameter {
    // this attribute is provided by the caller
    protected boolean isCursor;

    // these attributes are generated by prepare method
    protected int jdbcType;
    protected String typeName;
    protected boolean isTypeNameRequired;

    protected transient DatabasePlatform dbplatform = null;

    public OutputParameterForCallableStatement(DatabaseField field) {
        super(field);
    }

    public OutputParameterForCallableStatement(DatabaseField field, AbstractSession session) {
        this(field, session, false);
    }

    public OutputParameterForCallableStatement(DatabaseField field, AbstractSession session, boolean isCursor) {
        this(field);
        this.isCursor = isCursor;
        prepare(session);
    }

    public OutputParameterForCallableStatement(OutputParameterForCallableStatement outParameter) {
        super(outParameter.obj);
        this.isCursor = outParameter.isCursor;
        this.jdbcType = outParameter.jdbcType;
        this.typeName = outParameter.typeName;
        this.isTypeNameRequired = outParameter.isTypeNameRequired;
    }

    protected OutputParameterForCallableStatement() {
    }

    public void setIsCursor(boolean isCursor) {
        this.isCursor = isCursor;
    }

    // make sure to call prepare() method after this
    public boolean isCursor() {
        return isCursor;
    }

    public boolean isTypeNameRequired() {
        return isTypeNameRequired;
    }

    public int getJdbcType() {
        return jdbcType;
    }

    public String getTypeName() {
        return typeName;
    }

    public DatabaseField getOutputField() {
        return (DatabaseField)obj;
    }

    public void prepare(AbstractSession session) {
        dbplatform = session.getPlatform();
        if (isCursor()) {
            jdbcType = dbplatform.getCursorCode();// Oracle code for cursors
        } else {
            jdbcType = dbplatform.getJDBCType(getOutputField());
            if (obj instanceof ObjectRelationalDatabaseField) {
                isTypeNameRequired = true;
                typeName = ((ObjectRelationalDatabaseField)obj).getSqlTypeName();
            } else {
                isTypeNameRequired = dbplatform.requiresTypeNameToRegisterOutputParameter();
                if (isTypeNameRequired) {
                    typeName = dbplatform.getJdbcTypeName(jdbcType);
                }
            }
        }
    }

    @Override
    public void set(DatabasePlatform platform, PreparedStatement statement, int parameterIndex, AbstractSession session) throws SQLException {
        if (isTypeNameRequired) {
            platform.registerOutputParameter((CallableStatement)statement, parameterIndex, jdbcType, typeName);
        } else {
            platform.registerOutputParameter((CallableStatement)statement, parameterIndex, jdbcType);
        }
    }

    @Override
    public void set(DatabasePlatform platform, CallableStatement statement, String parameterName, AbstractSession session) throws SQLException {
        if (isTypeNameRequired) {
            platform.registerOutputParameter(statement, parameterName, jdbcType, typeName);
        } else {
            platform.registerOutputParameter(statement, parameterName, jdbcType);
        }
    }

    @Override
    public String toString() {
        return "=> " + getOutputField().getNameDelimited(dbplatform);
    }
}
