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

import java.util.Iterator;
import javax.jdo.FetchPlan;
import javax.jdo.JDOHelper;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.shoppingcart.Cart;
import org.apache.jdo.tck.pc.shoppingcart.CartEntry;
import org.apache.jdo.tck.pc.shoppingcart.Product;
import org.apache.jdo.tck.pc.shoppingcart.Undetachable;

/** */
public abstract class DetachTest extends JDO_Test {

  protected Cart cart1;
  protected CartEntry cartEntry1;
  protected Product product1;

  protected Object cart1oid;

  protected Cart goldenCart;
  protected CartEntry goldenCartEntry;

  protected Object[] cartClosure;

  protected static final String CART_ENTRIES = "Cart.entries";
  protected static final String CARTENTRY_CART = "CartEntry.cart";
  protected static final String CARTENTRY_PRODUCT = "CartEntry.product";
  protected static final String[] CART_FETCH_GROUPS =
      new String[] {FetchPlan.DEFAULT, CART_ENTRIES, CARTENTRY_CART, CARTENTRY_PRODUCT};

  /** Creates a new instance of DetachTest */
  public DetachTest() {}

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    addTearDownClass(CartEntry.class);
    addTearDownClass(Cart.class);
    addTearDownClass(Product.class);
    addTearDownClass(Undetachable.class);

    Product goldenProduct = new Product("PRODUCT1", "Product 1");
    goldenCart = new Cart("142857");
    goldenCartEntry = goldenCart.newCartEntry(goldenProduct, 100);

    product1 = new Product("PRODUCT1", "Product 1");
    cart1 = new Cart("142857");
    cartEntry1 = new CartEntry(cart1, goldenCartEntry.getId(), product1, 100);
    cartClosure = new Object[] {cart1, cartEntry1, product1};

    getPM().currentTransaction().begin();
    pm.makePersistent(cart1);
    cart1oid = pm.getObjectId(cart1);
    pm.currentTransaction().commit();
  }

  /** */
  protected void setCartFetchGroups() {
    FetchPlan fp = getPM().getFetchPlan();
    fp.setGroups(CART_FETCH_GROUPS);
    fp.setMaxFetchDepth(2);
  }

  /**
   * @param location location
   * @param obj object
   * @param persistent persistent option
   */
  protected void checkState(String location, Object obj, boolean persistent) {
    if (persistent) {
      if (JDOHelper.isPersistent(obj)) return;
    } else if (JDOHelper.isDetached(obj)) return;
    appendMessage(
        location
            + " should be "
            + (persistent ? "persistent" : "detached")
            + " but is not. The object state is: "
            + states[currentState(obj)]
            + " "
            + getStateOfInstance(obj));
  }

  /**
   * @param location location
   * @param expected expected value
   * @param actual actual value
   */
  protected void reportDifference(String location, long expected, long actual) {
    appendMessage(location + NL + "expected: " + expected + NL + "actual: " + actual);
  }

  /**
   * @param location location
   * @param expected expected value
   * @param actual actual value
   */
  protected void reportDifference(String location, Object expected, Object actual) {
    appendMessage(location + NL + "expected: " + expected + NL + "  actual: " + actual);
  }

  /**
   * @param location location
   * @param cart cart
   */
  protected void checkCartValues(String location, Cart cart) {
    checkCartValues(location, cart, false);
  }

  /**
   * @param location location
   * @param cart cart
   * @param persistent persistent option
   */
  protected void checkCartValues(String location, Cart cart, boolean persistent) {
    checkState(location + "Cart instance", cart, persistent);
    if (!goldenCart.getCustomerId().equals(cart.getCustomerId()))
      reportDifference(
          location + " differences in cart.customerId",
          goldenCart.getCustomerId(),
          cart.getCustomerId());
    Iterator<CartEntry> goldenCartEntries = goldenCart.getEntries();
    Iterator<CartEntry> cartEntries = cart.getEntries();
    while (cartEntries.hasNext()) {
      CartEntry goldenCartEntry = goldenCartEntries.next();
      CartEntry cartEntry = cartEntries.next();
      checkState(location + "CartEntry instance", cartEntry, persistent);
      Cart cartEntryCart = cartEntry.getCart();
      if (cartEntryCart != cart) {
        reportDifference(location + " incorrect value for cartEntry.cart", cart, cartEntryCart);
      }
      if (goldenCartEntry.getId() != cartEntry.getId())
        reportDifference(
            location + " differences in cartEntry.id", goldenCartEntry.getId(), cartEntry.getId());
      if (goldenCartEntry.getQuantity() != cartEntry.getQuantity())
        reportDifference(
            location + " differences in cartEntry.quantity",
            goldenCartEntry.getQuantity(),
            cartEntry.getQuantity());
      Product goldenProduct = goldenCartEntry.getProduct();
      Product product = cartEntry.getProduct();
      checkState(location + "Product instance", product, persistent);
      if (!goldenProduct.getDescription().equals(product.getDescription()))
        reportDifference(
            location + " differences in product.description",
            goldenProduct.getDescription(),
            product.getDescription());
    }
  }

  /**
   * @param ASSERTION_FAILED assertion
   * @return cart
   */
  protected Cart createDetachedInstance(String ASSERTION_FAILED) {
    getPM().currentTransaction().begin();
    setCartFetchGroups();
    pm.retrieveAll(cartClosure);
    pm.setDetachAllOnCommit(true);
    pm.currentTransaction().commit();
    checkCartValues(ASSERTION_FAILED + "after commit with DetachAllOnCommit,", cart1);
    failOnError();
    pm.setDetachAllOnCommit(false);
    return cart1;
  }
}
