/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.api.persistencemanager;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collection;
import java.util.HashSet;
import javax.jdo.datastore.JDOConnection;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> DataStoreConnection <br>
 * <B>Keywords:</B> <br>
 * <B>Assertion ID:</B> A12.5.2-1 <br>
 * <B>Assertion Description: </B> In order for the application to perform some datastore-specific
 * functions, such as to execute a query that is not directly supported by JDO, applications might
 * need access to the datastore connection used by the JDO implementation. This method returns a
 * wrapped connection that can be cast to the appropriate datastore connection and used by the
 * application. The capability to get the datastore connection is indicated by the optional feature
 * string javax.jdo.option.GetDataStoreConnection.
 */
public class DataStoreConnection extends PersistenceManagerTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A12.5.2-1 (DataStoreConnection) failed: ";

  protected PCPoint goldenPoint;

  /**
   * The <code>main</code> is called when the class is directly executed from the command line.
   *
   * @param args The arguments passed to the program.
   */
  public static void main(String[] args) {
    BatchTestRunner.run(DataStoreConnection.class);
  }

  /** */
  @Override
  protected void localSetUp() {
    addTearDownClass(PCPoint.class);
    PCPoint point = new PCPoint(50, 100);
    goldenPoint = new PCPoint(point.getX(), point.getY());
    getPM().currentTransaction().begin();
    pm.makePersistent(point);
    pm.currentTransaction().commit();
  }

  /** */
  public void testDataStoreConnection() {
    if (!(isDataStoreConnectionSupported() && isSQLSupported())) {
      printUnsupportedOptionalFeatureNotTested(
          this.getClass().getName(), "getDataStoreConnection AND SQLSupported.");
      return;
    }
    getPM().currentTransaction().setOptimistic(false);
    executeSQLWithDataStoreConnection();
    if (!isOptimisticSupported()) {
      printUnsupportedOptionalFeatureNotTested(
          this.getClass().getName(), "getDataStoreConnection AND SQLSupported AND Optimistic.");
      return;
    }
    getPM().currentTransaction().setOptimistic(true);
    executeSQLWithDataStoreConnection();
  }

  private void executeSQLWithDataStoreConnection() {
    String schema = getPMFProperty("javax.jdo.mapping.Schema");
    String sql = "SELECT X, Y FROM " + schema + ".PCPoint";
    JDOConnection jconn = null;
    try {
      getPM().currentTransaction().begin();
      jconn = pm.getDataStoreConnection();
      Connection conn = (Connection) jconn;
      if (conn.getAutoCommit()) {
        appendMessage(ASSERTION_FAILED + "Autocommit must not be true in JDO connection.");
      }
      PreparedStatement ps = conn.prepareStatement(sql);
      ResultSet rs = ps.executeQuery();
      Collection<PCPoint> actuals = new HashSet<>();
      while (rs.next()) {
        PCPoint p = new PCPoint(rs.getInt(1), rs.getInt(2));
        actuals.add(p);
      }
      if (actuals.size() != 1) {
        appendMessage(
            ASSERTION_FAILED
                + "Wrong size of result of "
                + sql
                + NL
                + "expected: 1, actual: "
                + actuals.size());
      } else {
        PCPoint actual = actuals.iterator().next();
        if (goldenPoint.getX() != actual.getX() || !goldenPoint.getY().equals(actual.getY())) {
          appendMessage(
              ASSERTION_FAILED
                  + "Wrong values of PCPoint from SQL"
                  + "expected x: "
                  + goldenPoint.getX()
                  + ", y: "
                  + goldenPoint.getX()
                  + NL
                  + "actual x: "
                  + actual.getX()
                  + ", y: "
                  + actual.getX());
        }
      }
    } catch (Exception ex) {
      appendMessage(ASSERTION_FAILED + " caught exception:" + ex);
    } finally {
      jconn.close();
      getPM().currentTransaction().commit();
      failOnError();
    }
  }
}
