/*
 * 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.jdo.tck.query.jdoql;

import java.util.Iterator;
import java.util.List;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.pc.mylib.PrimitiveTypes;
import org.apache.jdo.tck.query.QueryTest;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Query with ignoreCache=false. <br>
 * <B>Keywords:</B> query <br>
 * <B>Assertion ID:</B> A14.6.1-7. <br>
 * <B>Assertion Description: </B> With ignoreCache set to false:
 *
 * <UL>
 *   <LI>if instances were made persistent in the current transaction, the instances will be
 *       considered part of the candidate instances.
 *   <LI>if instances were deleted in the current transaction, the instances will not be considered
 *       part of the candidate instances.
 *   <LI>modified instances will be evaluated using their current transactional values.
 * </UL>
 */
public class IgnoreCacheFalse extends QueryTest {

  /** */
  private static final String ASSERTION_FAILED = "Assertion A14.6.1-7 (IgnoreCacheFalse) 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(IgnoreCacheFalse.class);
  }

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

  /** */
  public void test() {
    pm = getPM();

    try {
      // set ignoreCache flag
      pm.setIgnoreCache(false);
      runTestNewInstance(pm);
      runTestDeletedInstance(pm);
      runTestModifiedInstance(pm);
    } finally {
      pm.close();
      pm = null;
    }
  }

  /** */
  void runTestNewInstance(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    tx.begin();

    // create new instance
    PrimitiveTypes newInstance = new PrimitiveTypes();
    newInstance.setId(98L);
    newInstance.setIntNotNull(98);
    pm.makePersistent(newInstance);

    List<PrimitiveTypes> result =
        pm.newQuery(PrimitiveTypes.class, "intNotNull == 98").executeList();
    // check result
    if (result.isEmpty())
      fail(ASSERTION_FAILED, "Query should find new instance, but query result is empty");
    Iterator<PrimitiveTypes> i = result.iterator();
    PrimitiveTypes p = i.next();
    if (p.getId() != 98L)
      fail(ASSERTION_FAILED, "Query returned wrong instance with id " + p.getId());
    if (i.hasNext()) fail(ASSERTION_FAILED, "Query returned more than one instance");

    if (debug) logger.debug("New instance is part of query result");

    tx.rollback();
  }

  /** */
  void runTestDeletedInstance(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    tx.begin();

    List<PrimitiveTypes> tmp = pm.newQuery(PrimitiveTypes.class, "id == 3").executeList();
    PrimitiveTypes instance3 = tmp.iterator().next();
    pm.deletePersistent(instance3);

    List<PrimitiveTypes> result =
        pm.newQuery(PrimitiveTypes.class, "intNotNull == 3").executeList();
    // check result
    if (result.isEmpty()) {
      if (debug) logger.debug("deleted instance not part of query result.");
    } else {
      // query result not empty => problem
      PrimitiveTypes p = result.iterator().next();
      if (JDOHelper.isDeleted(p))
        fail(ASSERTION_FAILED, "query result should not include deleted instance");
      else fail(ASSERTION_FAILED, "query returns suspicious isntance " + p);
    }
    tx.rollback();
  }

  /** */
  void runTestModifiedInstance(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    tx.begin();

    List<PrimitiveTypes> tmp = pm.newQuery(PrimitiveTypes.class, "id == 5").executeList();
    PrimitiveTypes instance5 = tmp.iterator().next();
    instance5.setIntNotNull(99);

    List<PrimitiveTypes> result =
        pm.newQuery(PrimitiveTypes.class, "intNotNull == 99").executeList();
    // check result
    if (result.isEmpty()) {
      fail(ASSERTION_FAILED, "Query should find modified instance, but query result is empty");
    }
    Iterator<PrimitiveTypes> i = result.iterator();
    PrimitiveTypes p = i.next();
    if (p.getId() != 5L)
      fail(ASSERTION_FAILED, "Query returned wrong instance with id " + p.getId());
    if (p.getIntNotNull() != 99)
      fail(
          ASSERTION_FAILED,
          "Query returned instance with wrong intNotNull field value " + p.getIntNotNull());
    if (i.hasNext()) fail(ASSERTION_FAILED, "Query returned more than one instance");

    if (debug) logger.debug("Modified instance is part of query result");

    tx.rollback();
  }
}
