package com.mockobjects.sql;

import com.mockobjects.MockObject;
import com.mockobjects.ReturnObjectList;
import com.mockobjects.ExpectationList;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;

/**
 * @version $Revision: 1.3 $
 */
class CommonMockResultSetMetaData extends MockObject implements ResultSetMetaData {
    private final ReturnObjectList myNames =
        new ReturnObjectList("MockResultSetMetaData.columnNames");
    private final ReturnObjectList myTypes =
        new ReturnObjectList("MockResultSetMetaData.columnTypes");
    private final ReturnObjectList myClassNames =
        new ReturnObjectList("MockResultSetMetaData.columnClassNames");
    private int myColumnCount;
    private final ExpectationList myColumnTypeIndexes =
        new ExpectationList("Column Type Indexes");
    private final ExpectationList myColumnNameIndexes =
        new ExpectationList("Column Name Indexes");
    private final ExpectationList myColumnClassNameIndexes =
        new ExpectationList("Column Class Name Indexes");

    /**
     * Value to return from getColumnCount.
     */
    public void setupGetColumnCount(int aColumnCount) {
        myColumnCount = aColumnCount;
    }

    /**
     * An array of column names in the order they appear in the
     * resultSet.
     */
    public void setupAddColumnNames(String[] allNames) {
        if (allNames != null) {
            for (int i = 0; i < allNames.length; i++) {
                setupAddColumnName(allNames[i]);
            }
        }
    }

    /**
     * The next column name in the resultSet.
     */
    public void setupAddColumnName(String aName) {
        this.myNames.addObjectToReturn(aName);
    }

    /**
     * An array of column SQL types in the order they appear in the
     * resultSet.
     */
    public void setupAddColumnTypes(int[] allTypes) {
        if (allTypes != null) {
            for (int i = 0; i < allTypes.length; i++) {
                setupAddColumnType(allTypes[i]);
            }
        }
    }

    /**
     * The next column's SQL type in the resultSet as an int.
     */
    public void setupAddColumnType(int aType) {
        this.myTypes.addObjectToReturn(aType);
    }

    /**
     * Returns value passed to setupGetColumnCount.
     * @see ResultSetMetaData#getColumnCount()
     */
    public int getColumnCount() throws SQLException {
        return myColumnCount;
    }

    /**
     * Returns the column name.
     * DOES NOT SUPPORT THE aColumnIndex PARAMETER.
     * You must call getColumnName in order, first to last.
     * Column names may be added with setupAddColumnName.
     * or setupAddColumnNames.
     * @see ResultSetMetaData#getColumnName(int)
     */
    public String getColumnName(int aColumnIndex) throws SQLException {
        myColumnNameIndexes.addActual(aColumnIndex);
        return (String) myNames.nextReturnObject();
    }

    /**
     * Adds an expectation for a column index to be passed to getColumnName
     * @see MockResultSetMetaData#getColumnName(int)
     */
    public void addExpectedColumnNameIndex(int aColumnIndex){
        myColumnNameIndexes.addExpected(aColumnIndex);
    }

    /**
     * Returns the column SQL type.
     * DOES NOT SUPPORT THE aColumnIndex PARAMETER.
     * You must call getColumnType in order, first to last.
     * Column SQL types may be added with setupAddColumnType.
     * @see ResultSetMetaData#getColumnType(int)
     */
    public int getColumnType(int aColumnIndex) throws SQLException {
        myColumnTypeIndexes.addActual(aColumnIndex);
        return ((Integer) myTypes.nextReturnObject()).intValue();
    }

    /**
     * Adds an expectation for a column index to be passed to getColumnType
     * @see MockResultSetMetaData#getColumnType(int)
     */
    public void addExpectedColumnTypeIndex(int aColumnIndex){
        myColumnTypeIndexes.addExpected(aColumnIndex);
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isAutoIncrement(int)
     */
    public boolean isAutoIncrement(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isCaseSensitive(int)
     */
    public boolean isCaseSensitive(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isSearchable(int)
     */
    public boolean isSearchable(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isCurrency(int)
     */
    public boolean isCurrency(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isNullable(int)
     */
    public int isNullable(int arg0) throws SQLException {
        notImplemented();
        return 0;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isSigned(int)
     */
    public boolean isSigned(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns 0.
     * @see ResultSetMetaData#getColumnDisplaySize(int)
     */
    public int getColumnDisplaySize(int arg0) throws SQLException {
        notImplemented();
        return 0;
    }

    /**
     * Calls notImplemented. Returns null.
     * @see ResultSetMetaData#getColumnLabel(int)
     */
    public String getColumnLabel(int arg0) throws SQLException {
        notImplemented();
        return null;
    }

    /**
     * Calls notImplemented. Returns null.
     * @see ResultSetMetaData#getColumnTypeName(int)
     */
    public String getColumnTypeName(int arg0) throws SQLException {
        notImplemented();
        return null;
    }

    /**
     * Calls notImplemented. Returns null.
     * @see ResultSetMetaData#getSchemaName(int)
     */
    public String getSchemaName(int arg0) throws SQLException {
        notImplemented();
        return null;
    }

    /**
     * Calls notImplemented. Returns 0.
     * @see ResultSetMetaData#getPrecision(int)
     */
    public int getPrecision(int arg0) throws SQLException {
        notImplemented();
        return 0;
    }

    /**
     * Calls notImplemented. Returns 0.
     * @see ResultSetMetaData#getScale(int)
     */
    public int getScale(int arg0) throws SQLException {
        notImplemented();
        return 0;
    }

    /**
     * Calls notImplemented. Returns null.
     * @see ResultSetMetaData#getTableName(int)
     */
    public String getTableName(int arg0) throws SQLException {
        notImplemented();
        return null;
    }

    /**
     * Calls notImplemented. Returns null.
     * @see ResultSetMetaData#getCatalogName(int)
     */
    public String getCatalogName(int arg0) throws SQLException {
        notImplemented();
        return null;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isReadOnly(int)
     */
    public boolean isReadOnly(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isWritable(int)
     */
    public boolean isWritable(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * Calls notImplemented. Returns false.
     * @see ResultSetMetaData#isDefinitelyWritable(int)
     */
    public boolean isDefinitelyWritable(int arg0) throws SQLException {
        notImplemented();
        return false;
    }

    /**
     * An array of column class names in the order they appear in the
     * resultSet.
     */
    public void setupAddColumnClassNames(String[] allNames) {
        if (allNames != null) {
            for (int i = 0; i < allNames.length; i++) {
                setupAddColumnClassName(allNames[i]);
            }
        }
    }

    /**
     * The next column class name in the resultSet.
     */
    public void setupAddColumnClassName(String aName) {
        this.myClassNames.addObjectToReturn(aName);
    }

    /**
     * Returns the column class name.
     * DOES NOT SUPPORT THE aColumnIndex PARAMETER.
     * You must call getColumnClassName in order, first to last.
     * Column class names may be added with setupAddColumnClassName.
     * or setupAddColumnClassNames.
     * @see ResultSetMetaData#getColumnClassName(int)
     */
    public String getColumnClassName(int aColumnIndex) throws SQLException {
        myColumnClassNameIndexes.addActual(aColumnIndex);
        return (String) myClassNames.nextReturnObject();
    }

    /**
     * Adds an expectation for a column index to be passed to getColumnClassName
     * @see MockResultSetMetaData#getColumnClassName(int)
     */
    public void addExpectedColumnClassNameIndex(int aColumnIndex){
        myColumnClassNameIndexes.addExpected(aColumnIndex);
    }

}
