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