/*
 * 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.Collection;
import java.util.HashSet;
import org.apache.jdo.tck.pc.shoppingcart.Cart;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Test DetachCopy <br>
 * <B>Keywords:</B> detachCopy detach <br>
 * <B>Assertion IDs:</B> A12.6.8-13, A12.6.8-18, A12.6.8-19, A12.6.8-20 <br>
 * <B>Assertion Description: </B> For each instance in the parameter Collection, a corresponding
 * detached copy is returned. Each field in the persistent instance is handled based on its type and
 * whether the field is contained in the fetch group for the persistence-capable class. If there are
 * duplicates in the parameter Collection, the corresponding detached copy is used for each such
 * duplicate.
 */
public class DetachCopy extends DetachTest {

  private static final String ASSERTION_FAILED =
      "Assertion A12.6.8-13, A12.6.8-18, A12.6.8-19, A12.6.8-20" + " (DetachCopy) 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(DetachCopy.class);
  }

  /** */
  public void testDetachCopy() {
    getPM().currentTransaction().begin();
    setCartFetchGroups();
    // pm.retrieveAll(cartClosure);
    Cart cartDetached = pm.detachCopy(cart1);
    checkCartValues(ASSERTION_FAILED + "after detachCopy," + NL, cartDetached);
    pm.currentTransaction().commit();
    failOnError();
  }

  /** */
  public void testDetachCopyAllCollection() {
    getPM().currentTransaction().begin();
    setCartFetchGroups();
    // pm.retrieveAll(cartClosure);
    Collection<Cart> instances = new HashSet<>();
    instances.add(cart1);
    Collection<Cart> detached = pm.detachCopyAll(instances);
    Cart cartDetached = detached.iterator().next();
    checkCartValues(ASSERTION_FAILED + "after detachCopyAll(Collection)," + NL, cartDetached);
    pm.currentTransaction().commit();
    failOnError();
  }

  /** */
  public void testDetachCopyAllArray() {
    getPM().currentTransaction().begin();
    setCartFetchGroups();
    // pm.retrieveAll(cartClosure);
    Object[] instances = new Object[] {cart1};
    Object[] detached = pm.detachCopyAll(instances);
    Cart cartDetached = (Cart) detached[0];
    checkCartValues(ASSERTION_FAILED + "after detachCopyAll(Object[])," + NL, cartDetached);
    pm.currentTransaction().commit();
    failOnError();
  }
}
