// Copyright (C) 2011 The Android Open Source Project
//
// Licensed 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 com.google.gwtorm.jdbc;

import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.gwtorm.schema.sql.SqlDialect;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

@RunWith(Parameterized.class)
public class TestJdbcAccessTotalUpdateCount extends AbstractTestJdbcAccess {

  public TestJdbcAccessTotalUpdateCount(IterableProvider<Data> dataProvider) throws SQLException {
    super(dataProvider);
  }

  @Override
  protected void assertCorrectUpdating(PreparedStatement ps, int... ids) throws SQLException {
    verify(dialect).executeBatch(ps);
  }

  @Override
  protected void assertCorrectAttempting(PreparedStatement ps, int... ids) throws SQLException {
    assertUsedNonBatchingOnly(ps, ids);
  }

  @Override
  protected SqlDialect createDialect() throws SQLException {
    SqlDialect dialect = mock(SqlDialect.class);
    when(dialect.canDetermineIndividualBatchUpdateCounts()).thenReturn(FALSE);
    when(dialect.canDetermineTotalBatchUpdateCount()).thenReturn(TRUE);
    when(dialect.executeBatch(any(PreparedStatement.class)))
        .thenAnswer(
            new Answer<Integer>() {

              @Override
              public Integer answer(InvocationOnMock invocation) throws Throwable {
                if (sqlException != null) {
                  throw sqlException;
                }
                if (totalUpdateCount == null) {
                  throw new IllegalStateException("totalCount is not set");
                }
                return totalUpdateCount;
              }
            });
    when(dialect.convertError(any(String.class), any(String.class), any(SQLException.class)))
        .thenCallRealMethod();

    return dialect;
  }
}
