/*
 * 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.query.api;

import java.util.ArrayList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.query.QueryTest;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Execute Query with Array <br>
 * <B>Keywords:</B> query <br>
 * <B>Assertion ID:</B> A14.6.1-6. <br>
 * <B>Assertion Description: </B> The <code>executeWithArray</code> method is similar to the <code>
 * execute</code> method, but takes its parameters from an array instance. The array contains <code>
 * Object</code>s, in which the positional <code>Object</code> is the value to use in the query for
 * that parameter. Unlike <code>execute</code>, there is no limit on the number of parameters.
 */
public class ExecuteQueryWithArray extends QueryTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A14.6.1-6 (ExecuteQueryWithArray) failed: ";

  /**
   * 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(ExecuteQueryWithArray.class);
  }

  /** */
  public void testPositive() {
    PersistenceManager pm = getPM();

    runTestExecuteQueryWithArray01(pm);
    runTestExecuteQueryWithArray02(pm);
  }

  /** */
  private void runTestExecuteQueryWithArray01(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {

      tx.begin();

      Query<PCPoint> query = pm.newQuery(PCPoint.class);
      query.setCandidates(pm.getExtent(PCPoint.class, false));
      query.declareParameters("Integer param");
      query.setFilter("x == param");

      Object[] actualParams = {Integer.valueOf(2)};
      Object results = query.executeWithArray(actualParams);

      // check query result
      List<PCPoint> expected = new ArrayList<>();
      PCPoint p3 = new PCPoint(2, 2);
      expected.add(p3);
      expected = getFromInserted(expected);
      printOutput(results, expected);
      checkQueryResultWithoutOrder(ASSERTION_FAILED, "x == param", results, expected);

      tx.commit();
      tx = null;
      if (debug) logger.debug("Test ExecuteQueryWithArray01 - Passed\n");
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestExecuteQueryWithArray02(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();

      Query<PCPoint> query = pm.newQuery(PCPoint.class);
      query.setCandidates(pm.getExtent(PCPoint.class, false));
      query.declareParameters("Integer param1, Integer param2");
      query.setFilter("x == param1 && y == param2");

      Object[] actualParams = {Integer.valueOf(2), Integer.valueOf(2)};
      Object results = query.executeWithArray(actualParams);

      // check query result
      List<PCPoint> expected = new ArrayList<>();
      PCPoint p3 = new PCPoint(2, 2);
      expected.add(p3);
      expected = getFromInserted(expected);
      printOutput(results, expected);
      checkQueryResultWithoutOrder(
          ASSERTION_FAILED, "x == param1 && y == param2", results, expected);
      tx.commit();
      tx = null;
      if (debug) logger.debug("Test ExecuteQueryWithArray02 - Passed\n");
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    addTearDownClass(PCPoint.class);
    loadAndPersistPCPoints(getPM());
  }
}
