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

import java.util.ArrayList;
import java.util.Collection;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.api.persistencemanager.PersistenceManagerTest;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.pc.mylib.PCPoint2;
import org.apache.jdo.tck.pc.mylib.PCRect;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Retrieve <br>
 * <B>Keywords:</B> cache <br>
 * <B>Assertion IDs:</B> A12.6.1-2, A12.6.1-5 <br>
 * <B>Assertion Description: </B> These methods request the PersistenceManager to load all
 * persistent fields into the parameter instances. Subsequent to this call, the application might
 * call makeTransient on the parameter instances, and the fields can no longer be touched by the
 * PersistenceManager. The PersistenceManager might also retrieve related instances according to a
 * pre-read policy (not specified by JDO). The JDO PersistenceManager loads persistent values from
 * the datastore into the instance and if the class of the instance implements InstanceCallbacks
 * calls jdoPostLoad.
 */
public class Retrieve extends PersistenceManagerTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A12.6.1-2, A12.6.1-5 (Retrieve) 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(Retrieve.class);
  }

  private PCPoint p1 = null;
  private String p1print = null;
  private PCPoint p2 = null;
  private PCPoint2 p3 = null;
  private PCRect rect = null;

  private static final Integer one = Integer.valueOf(1);
  private static final Integer three = Integer.valueOf(3);

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

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

    runTestRetrieve(pm);
    runTestRetrieveAllWithCollection(pm);
    runTestRetrieveAllWithArray(pm);
    runTestRetrieveAllWithCollectionDFGtrue(pm);
    runTestRetrieveAllWithArrayDFGtrue(pm);
    runTestRetrieveAllWithCollectionDFGfalse(pm);
    runTestRetrieveAllWithArrayDFGfalse(pm);

    pm.close();
    pm = null;
  }

  /**
   * @param pm the PersistenceManager
   */
  private void runTestRetrieve(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      pm.retrieve(p1);
      pm.retrieve(p3);
      pm.retrieve(rect);
      pm.makeTransient(p1);
      pm.makeTransient(p3);
      pm.makeTransient(rect);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      checkRectP1();
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithCollection(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Collection<Object> coll = new ArrayList<>();
      coll.add(p1);
      coll.add(p3);
      coll.add(rect);
      pm.retrieveAll(coll);
      pm.makeTransientAll(coll);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      checkRectP1();
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithCollectionDFGtrue(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Collection<Object> coll = new ArrayList<>();
      coll.add(p1);
      coll.add(p3);
      coll.add(rect);
      pm.retrieveAll(coll, true);
      pm.makeTransientAll(coll);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      // checkRectP1(); p1 is not in the default fetch group by default
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithCollectionDFGfalse(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Collection<Object> coll = new ArrayList<>();
      coll.add(p1);
      coll.add(p3);
      coll.add(rect);
      pm.retrieveAll(coll, false);
      pm.makeTransientAll(coll);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      checkRectP1();
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithArray(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Object[] objs = new Object[3];
      objs[0] = p1;
      objs[1] = p3;
      objs[2] = rect;
      pm.retrieveAll(objs);
      pm.makeTransientAll(objs);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      checkRectP1();
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithArrayDFGtrue(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Object[] objs = new Object[3];
      objs[0] = p1;
      objs[1] = p3;
      objs[2] = rect;
      pm.retrieveAll(true, objs);
      pm.makeTransientAll(objs);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      // checkRectP1(); p1 is not in the default fetch group by default
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void runTestRetrieveAllWithArrayDFGfalse(PersistenceManager pm) {
    createObjects(pm);
    Transaction tx = pm.currentTransaction();
    try {
      tx.begin();
      Object[] objs = new Object[3];
      objs[0] = p1;
      objs[1] = p3;
      objs[2] = rect;
      pm.retrieveAll(false, objs);
      pm.makeTransientAll(objs);
      tx.commit();
      tx = null;
      checkP1();
      checkP3();
      checkRectP1();
      checkRectId();
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void createObjects(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    try {
      tx.setRetainValues(false);
      tx.begin();
      p1 = new PCPoint(1, 1);
      p1print = p1.toString();
      p2 = new PCPoint(2, 2);
      p3 = new PCPoint2(3, 3);
      rect = new PCRect(100, p1, p2);
      pm.makePersistent(p1);
      pm.makePersistent(p2);
      pm.makePersistent(p3);
      pm.makePersistent(rect);
      if (debug) {
        logger.debug("p1: " + p1.name());
        logger.debug("p2: " + p2.name());
        logger.debug("p3: " + p3.name());
        logger.debug(
            "rect id: "
                + rect.getId()
                + ", upperLeft: "
                + rect.getUpperLeft().name()
                + ", lowerRight: "
                + rect.getLowerRight().name());
      }
      tx.commit();
      tx = null;
    } finally {
      if ((tx != null) && tx.isActive()) tx.rollback();
    }
  }

  /** */
  private void checkP1() {
    if (((p1.getX() != 1) || (!one.equals(p1.getY())))) {
      fail(
          ASSERTION_FAILED,
          "Error in p1 fields. Expected x:1, y:1; got x:" + p1.getX() + ", y:" + p1.getY());
    }
  }

  /** */
  private void checkP3() {
    if ((p3.getX() != 3) || (!three.equals(p3.getY()))) {
      fail(
          ASSERTION_FAILED,
          "Error in p3 fields. Expected x:3, y:3; got x:" + p3.getX() + ", y:" + p3.getY());
    }

    if (!p3.wasPostLoadCalled()) {
      fail(ASSERTION_FAILED, "missing call of jdoPostLoad for p3");
    }
  }

  /** */
  private void checkRectId() {
    if (rect.getId() == 0) {
      fail(ASSERTION_FAILED, "Error in rect field id. Expected id!= 0; got id:0");
    }
  }

  /** */
  private void checkRectP1() {
    if (rect.getUpperLeft() != p1) {
      fail(
          ASSERTION_FAILED,
          "Error in rect field upperLeft. Expected:" + p1print + ", got:" + rect.getUpperLeft());
    }
  }
}
