/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.dbcp2;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * A base delegating implementation of {@link Statement}.
 * <p>
 * All of the methods from the {@link Statement} interface simply check to see that the {@link Statement} is active, and
 * call the corresponding method on the "delegate" provided in my constructor.
 * <p>
 * Extends AbandonedTrace to implement Statement tracking and logging of code which created the Statement. Tracking the
 * Statement ensures that the Connection which created it can close any open Statement's on Connection close.
 *
 * @since 2.0
 */
public class DelegatingStatement extends AbandonedTrace implements Statement {

    /** My delegate. */
    private Statement statement;

    /** The connection that created me. **/
    private DelegatingConnection<?> connection;

    private boolean closed = false;

    /**
     * Create a wrapper for the Statement which traces this Statement to the Connection which created it and the code
     * which created it.
     *
     * @param statement
     *            the {@link Statement} to delegate all calls to.
     * @param connection
     *            the {@link DelegatingConnection} that created this statement.
     */
    public DelegatingStatement(final DelegatingConnection<?> connection, final Statement statement) {
        super(connection);
        this.statement = statement;
        this.connection = connection;
    }

    /**
     *
     * @throws SQLException
     *             thrown by the delegating statement.
     * @since 2.4.0 made public, was protected in 2.3.0.
     */
    public void activate() throws SQLException {
        if (statement instanceof DelegatingStatement) {
            ((DelegatingStatement) statement).activate();
        }
    }

    @Override
    public void addBatch(final String sql) throws SQLException {
        checkOpen();
        try {
            statement.addBatch(sql);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void cancel() throws SQLException {
        checkOpen();
        try {
            statement.cancel();
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    protected void checkOpen() throws SQLException {
        if (isClosed()) {
            throw new SQLException(this.getClass().getName() + " with address: \"" + this.toString() + "\" is closed.");
        }
    }

    @Override
    public void clearBatch() throws SQLException {
        checkOpen();
        try {
            statement.clearBatch();
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void clearWarnings() throws SQLException {
        checkOpen();
        try {
            statement.clearWarnings();
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    /**
     * Close this DelegatingStatement, and close any ResultSets that were not explicitly closed.
     */
    @Override
    public void close() throws SQLException {
        if (isClosed()) {
            return;
        }
        final List<SQLException> thrown = new ArrayList<>();
        try {
            if (connection != null) {
                connection.removeTrace(this);
                connection = null;
            }

            // The JDBC spec requires that a statement close any open
            // ResultSet's when it is closed.
            // FIXME The PreparedStatement we're wrapping should handle this for us.
            // See bug 17301 for what could happen when ResultSets are closed twice.
            final List<AbandonedTrace> resultSetList = getTrace();
            if (resultSetList != null) {
                final int size = resultSetList.size();
                final ResultSet[] resultSets = resultSetList.toArray(new ResultSet[size]);
                for (final ResultSet resultSet : resultSets) {
                    if (resultSet != null) {
                        try {
                            resultSet.close();
                        } catch (SQLException e) {
                            if (connection != null) {
                                // Does not rethrow e.
                                connection.handleException(e, false);
                            }
                            thrown.add(e);
                        }
                    }
                }
                clearTrace();
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    if (connection != null) {
                        // Does not rethrow e.
                        connection.handleException(e, false);
                    }
                    thrown.add(e);
                }
            }
        } finally {
            closed = true;
            statement = null;
            if (!thrown.isEmpty()) {
                throw new SQLExceptionList(thrown);
            }
        }
    }

    @Override
    public void closeOnCompletion() throws SQLException {
        checkOpen();
        try {
            Jdbc41Bridge.closeOnCompletion(statement);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public boolean execute(final String sql) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.execute(sql);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.execute(sql, autoGeneratedKeys);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean execute(final String sql, final int columnIndexes[]) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.execute(sql, columnIndexes);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean execute(final String sql, final String columnNames[]) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.execute(sql, columnNames);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public int[] executeBatch() throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeBatch();
        } catch (final SQLException e) {
            handleException(e);
            throw new AssertionError();
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long[] executeLargeBatch() throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeLargeBatch();
        } catch (final SQLException e) {
            handleException(e);
            return null;
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long executeLargeUpdate(final String sql) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeLargeUpdate(sql);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long executeLargeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeLargeUpdate(sql, autoGeneratedKeys);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long executeLargeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeLargeUpdate(sql, columnIndexes);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long executeLargeUpdate(final String sql, final String[] columnNames) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeLargeUpdate(sql, columnNames);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public ResultSet executeQuery(final String sql) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return DelegatingResultSet.wrapResultSet(this, statement.executeQuery(sql));
        } catch (final SQLException e) {
            handleException(e);
            throw new AssertionError();
        }
    }

    @Override
    public int executeUpdate(final String sql) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeUpdate(sql);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeUpdate(sql, autoGeneratedKeys);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int executeUpdate(final String sql, final int columnIndexes[]) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeUpdate(sql, columnIndexes);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int executeUpdate(final String sql, final String columnNames[]) throws SQLException {
        checkOpen();
        setLastUsedInParent();
        try {
            return statement.executeUpdate(sql, columnNames);
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    protected void finalize() throws Throwable {
        // This is required because of statement pooling. The poolable
        // statements will always be strongly held by the statement pool. If the
        // delegating statements that wrap the poolable statement are not
        // strongly held they will be garbage collected but at that point the
        // poolable statements need to be returned to the pool else there will
        // be a leak of statements from the pool. Closing this statement will
        // close all the wrapped statements and return any poolable statements
        // to the pool.
        close();
        super.finalize();
    }

    @Override
    public Connection getConnection() throws SQLException {
        checkOpen();
        return getConnectionInternal(); // return the delegating connection that created this
    }

    protected DelegatingConnection<?> getConnectionInternal() {
        return connection;
    }

    /**
     * Returns my underlying {@link Statement}.
     *
     * @return my underlying {@link Statement}.
     * @see #getInnermostDelegate
     */
    public Statement getDelegate() {
        return statement;
    }

    @Override
    public int getFetchDirection() throws SQLException {
        checkOpen();
        try {
            return statement.getFetchDirection();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getFetchSize() throws SQLException {
        checkOpen();
        try {
            return statement.getFetchSize();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public ResultSet getGeneratedKeys() throws SQLException {
        checkOpen();
        try {
            return DelegatingResultSet.wrapResultSet(this, statement.getGeneratedKeys());
        } catch (final SQLException e) {
            handleException(e);
            throw new AssertionError();
        }
    }

    /**
     * If my underlying {@link Statement} is not a {@code DelegatingStatement}, returns it, otherwise recursively
     * invokes this method on my delegate.
     * <p>
     * Hence this method will return the first delegate that is not a {@code DelegatingStatement} or {@code null} when
     * no non-{@code DelegatingStatement} delegate can be found by traversing this chain.
     * </p>
     * <p>
     * This method is useful when you may have nested {@code DelegatingStatement}s, and you want to make sure to obtain
     * a "genuine" {@link Statement}.
     * </p>
     *
     * @return The innermost delegate.
     *
     * @see #getDelegate
     */
    @SuppressWarnings("resource")
    public Statement getInnermostDelegate() {
        Statement s = statement;
        while (s != null && s instanceof DelegatingStatement) {
            s = ((DelegatingStatement) s).getDelegate();
            if (this == s) {
                return null;
            }
        }
        return s;
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long getLargeMaxRows() throws SQLException {
        checkOpen();
        try {
            return statement.getLargeMaxRows();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public long getLargeUpdateCount() throws SQLException {
        checkOpen();
        try {
            return statement.getLargeUpdateCount();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getMaxFieldSize() throws SQLException {
        checkOpen();
        try {
            return statement.getMaxFieldSize();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getMaxRows() throws SQLException {
        checkOpen();
        try {
            return statement.getMaxRows();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public boolean getMoreResults() throws SQLException {
        checkOpen();
        try {
            return statement.getMoreResults();
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean getMoreResults(final int current) throws SQLException {
        checkOpen();
        try {
            return statement.getMoreResults(current);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public int getQueryTimeout() throws SQLException {
        checkOpen();
        try {
            return statement.getQueryTimeout();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public ResultSet getResultSet() throws SQLException {
        checkOpen();
        try {
            return DelegatingResultSet.wrapResultSet(this, statement.getResultSet());
        } catch (final SQLException e) {
            handleException(e);
            throw new AssertionError();
        }
    }

    @Override
    public int getResultSetConcurrency() throws SQLException {
        checkOpen();
        try {
            return statement.getResultSetConcurrency();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getResultSetHoldability() throws SQLException {
        checkOpen();
        try {
            return statement.getResultSetHoldability();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getResultSetType() throws SQLException {
        checkOpen();
        try {
            return statement.getResultSetType();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public int getUpdateCount() throws SQLException {
        checkOpen();
        try {
            return statement.getUpdateCount();
        } catch (final SQLException e) {
            handleException(e);
            return 0;
        }
    }

    @Override
    public SQLWarning getWarnings() throws SQLException {
        checkOpen();
        try {
            return statement.getWarnings();
        } catch (final SQLException e) {
            handleException(e);
            throw new AssertionError();
        }
    }

    protected void handleException(final SQLException e) throws SQLException {
        if (connection != null) {
            connection.handleException(e);
        } else {
            throw e;
        }
    }

    /*
     * Note: This method was protected prior to JDBC 4.
     */
    @Override
    public boolean isClosed() throws SQLException {
        return closed;
    }

    protected boolean isClosedInternal() {
        return closed;
    }

    @Override
    public boolean isCloseOnCompletion() throws SQLException {
        checkOpen();
        try {
            return Jdbc41Bridge.isCloseOnCompletion(statement);
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean isPoolable() throws SQLException {
        checkOpen();
        try {
            return statement.isPoolable();
        } catch (final SQLException e) {
            handleException(e);
            return false;
        }
    }

    @Override
    public boolean isWrapperFor(final Class<?> iface) throws SQLException {
        if (iface.isAssignableFrom(getClass())) {
            return true;
        } else if (iface.isAssignableFrom(statement.getClass())) {
            return true;
        } else {
            return statement.isWrapperFor(iface);
        }
    }

    /**
     *
     * @throws SQLException
     *             thrown by the delegating statement.
     * @since 2.4.0 made public, was protected in 2.3.0.
     */
    public void passivate() throws SQLException {
        if (statement instanceof DelegatingStatement) {
            ((DelegatingStatement) statement).passivate();
        }
    }

    protected void setClosedInternal(final boolean closed) {
        this.closed = closed;
    }

    @Override
    public void setCursorName(final String name) throws SQLException {
        checkOpen();
        try {
            statement.setCursorName(name);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    /**
     * Sets my delegate.
     *
     * @param statement
     *            my delegate.
     */
    public void setDelegate(final Statement statement) {
        this.statement = statement;
    }

    @Override
    public void setEscapeProcessing(final boolean enable) throws SQLException {
        checkOpen();
        try {
            statement.setEscapeProcessing(enable);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void setFetchDirection(final int direction) throws SQLException {
        checkOpen();
        try {
            statement.setFetchDirection(direction);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void setFetchSize(final int rows) throws SQLException {
        checkOpen();
        try {
            statement.setFetchSize(rows);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    /**
     * @since 2.5.0
     */
    @Override
    public void setLargeMaxRows(final long max) throws SQLException {
        checkOpen();
        try {
            statement.setLargeMaxRows(max);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    private void setLastUsedInParent() {
        if (connection != null) {
            connection.setLastUsed();
        }
    }

    @Override
    public void setMaxFieldSize(final int max) throws SQLException {
        checkOpen();
        try {
            statement.setMaxFieldSize(max);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void setMaxRows(final int max) throws SQLException {
        checkOpen();
        try {
            statement.setMaxRows(max);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void setPoolable(final boolean poolable) throws SQLException {
        checkOpen();
        try {
            statement.setPoolable(poolable);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    @Override
    public void setQueryTimeout(final int seconds) throws SQLException {
        checkOpen();
        try {
            statement.setQueryTimeout(seconds);
        } catch (final SQLException e) {
            handleException(e);
        }
    }

    /**
     * Returns a String representation of this object.
     *
     * @return String
     */
    @Override
    public synchronized String toString() {
        return statement == null ? "NULL" : statement.toString();
    }

    @Override
    public <T> T unwrap(final Class<T> iface) throws SQLException {
        if (iface.isAssignableFrom(getClass())) {
            return iface.cast(this);
        } else if (iface.isAssignableFrom(statement.getClass())) {
            return iface.cast(statement);
        } else {
            return statement.unwrap(iface);
        }
    }
}
