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

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.jdo.FetchPlan;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.pc.mylib.PCRect;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Test TITLE <br>
 * <B>Keywords:</B> fetch plan <br>
 * <B>Assertion IDs:</B> 12.7.1-1 <br>
 * <B>Assertion Description: </B> public interface FetchPlan { String DEFAULT = "default"; String
 * ALL = "all"; int FETCH_SIZE_GREEDY = -1; int FETCH_SIZE_OPTIMAL = 0; int DETACH_LOAD_FIELDS = 1;
 * int DETACH_UNLOAD_FIELDS = 2; A12.7.1-1 [/** Add the fetchgroup to the set of active fetch
 * groups. Duplicate names will be removed. FetchPlan addGroup(String fetchGroupName); /** Remove
 * the fetch group from the set active fetch groups. FetchPlan removeGroup(String fetchGroupName);
 * /** Remove all active groups, including the default fetch group. FetchPlan clearGroups(); /**
 * Return an immutable Set of the names of all active fetch groups. Set getGroups(); /** Set a
 * Collection of group names to replace the current groups. Duplicate names will be removed.
 * FetchPlan setGroups(Collection fetchGroupNames); /** Set an array of group names to replace the
 * current groups. Duplicate names will be removed. FetchPlan setGroups(String[] fetchGroupNames);
 * /** Set a single group to replace the current groups. FetchPlan setGroup(String fetchGroupName);]
 * /** Set the roots for DetachAllOnCommit FetchPlan setDetachmentRoots(Collection roots); /** Get
 * the roots for DetachAllOnCommit Collection getDetachmentRoots(); /** Set the roots for
 * DetachAllOnCommit FetchPlan setDetachmentRootClasses(Class[] rootClasses); /** Get the roots for
 * DetachAllOnCommit Class[] getDetachmentRootClasses(); /** Set the maximum fetch depth. FetchPlan
 * setMaxFetchDepth(int fetchDepth); /** Get the maximum fetch depth. int getMaxFetchDepth();
 * A12.7.1-2 [/** Set the fetch size for large result set support. FetchPlan setFetchSize(int
 * fetchSize); /** Return the fetch size; 0 if not set; -1 for greedy fetching. int getFetchSize();]
 * A12.7.1-3 [/** Set detachment options FetchPlan setDetachmentOptions(int options); /** Return the
 * detachment options int getDetachmentOptions();]
 */
public class FetchPlanInterface extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED = "Assertion 12.7.1-1 (FetchPlanTest) 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(FetchPlanInterface.class);
  }

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

  /**
   * @param expected expected value
   * @param actual actual value
   * @return true if equal
   */
  protected <T> boolean setEquals(Collection<T> expected, Collection<T> actual) {
    if (expected == actual) return true;
    if (expected == null || actual == null) return false;
    Set<T> expectedSet = new HashSet<>(expected);
    Set<T> actualSet = new HashSet<>(actual);
    return expectedSet.equals(actualSet);
  }

  /**
   * @param message message
   * @param expected expected value
   * @param actual actual value
   */
  protected void failCompare(String message, Object expected, Object actual) {
    appendMessage(ASSERTION_FAILED + message);
    appendMessage("expected: " + expected);
    appendMessage("actual: " + actual);
  }

  /**
   * @param message message
   * @param expected expected value
   * @param actual actual value
   */
  protected void failCompare(String message, int expected, int actual) {
    appendMessage(ASSERTION_FAILED + message);
    appendMessage("expected: " + expected);
    appendMessage("actual: " + actual);
  }

  /** */
  public void testGroups() {
    checkDefaultGroups();
    checkClearGroups();
    checkSetGroup();
    checkAddGroup();
    checkRemoveGroup();
    checkClearGroups();
    checkSetGroupsCollection();
    checkSetGroupsArray();
    failOnError();
  }

  /** */
  public void testDetachmentRoots() {
    checkGetDetachmentRoots();
    checkSetDetachmentRoots();
    checkSetDetachmentRootClasses();
    failOnError();
  }

  /** */
  public void testDetachmentOptions() {
    int expectedOptions = FetchPlan.DETACH_LOAD_FIELDS + FetchPlan.DETACH_UNLOAD_FIELDS;
    FetchPlan fp = getPM().getFetchPlan();
    int initialOptions = fp.getDetachmentOptions();
    if (FetchPlan.DETACH_LOAD_FIELDS != initialOptions) {
      failCompare(
          "testDetachmentOptions(): wrong getDetachmentOptions() "
              + "after getPersistenceManager().",
          FetchPlan.DETACH_LOAD_FIELDS,
          initialOptions);
    }
    fp.setDetachmentOptions(expectedOptions);
    int actualOptions = fp.getDetachmentOptions();
    if (expectedOptions != actualOptions) {
      failCompare(
          "testDetachmentOptions(): wrong getDetachmentOptions() "
              + "after setDetachmentOptions().",
          expectedOptions,
          actualOptions);
    }
    cleanupPM();
    failOnError();
  }

  /** */
  public void testMaxFetchDepth() {
    int expectedMaxFetchDepth = 12;
    FetchPlan fp = getPM().getFetchPlan();
    fp.setMaxFetchDepth(expectedMaxFetchDepth);
    int actualMaxFetchDepth = fp.getMaxFetchDepth();
    if (expectedMaxFetchDepth != actualMaxFetchDepth) {
      failCompare(
          "testMaxFetchDepth(): wrong getMaxFetchDepth() " + "after setMaxFetchDepth().",
          expectedMaxFetchDepth,
          actualMaxFetchDepth);
    }
    cleanupPM();
    failOnError();
  }

  /** */
  public void testFetchSize() {
    int expectedFetchSize = 12;
    FetchPlan fp = getPM().getFetchPlan();
    fp.setFetchSize(expectedFetchSize);
    int actualFetchSize = fp.getFetchSize();
    if (expectedFetchSize != actualFetchSize) {
      failCompare(
          "testFetchSize(): wrong getFetchSize() " + "after setFetchSize().",
          expectedFetchSize,
          actualFetchSize);
    }
    cleanupPM();
    failOnError();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkDefaultGroups() {
    Set<String> expectedGroups = new HashSet<>();
    expectedGroups.add("default");
    FetchPlan fp = getPM().getFetchPlan();
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkDefaultGroups(): wrong getGroups() " + "after getPersistenceManager().",
          expectedGroups,
          groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkClearGroups() {
    Set<String> expectedGroups = new HashSet<>();
    FetchPlan fp = getPM().getFetchPlan();
    fp.clearGroups();
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkClearGroups(): wrong getGroups() " + "after clearGroups.", expectedGroups, groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkSetGroup() {
    Set<String> expectedGroups = new HashSet<>();
    expectedGroups.add("group1");
    FetchPlan fp = getPM().getFetchPlan();
    fp.setGroup("group1");
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkSetGroup(): wrong getGroups() " + "after setGroup.", expectedGroups, groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkAddGroup() {
    Set<String> expectedGroups = new HashSet<>();
    expectedGroups.add("default");
    expectedGroups.add("group1");
    FetchPlan fp = getPM().getFetchPlan();
    fp.addGroup("group1");
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkAddGroup(): wrong getGroups() " + "after addGroup.", expectedGroups, groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkRemoveGroup() {
    Set<String> expectedGroups = new HashSet<>();
    FetchPlan fp = getPM().getFetchPlan();
    fp.removeGroup("default");
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkRemoveGroup(): wrong getGroups() " + "after removeGroup.", expectedGroups, groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkSetGroupsCollection() {
    Set<String> expectedGroups = new HashSet<>();
    expectedGroups.add("default");
    expectedGroups.add("group1");
    expectedGroups.add("group2");
    FetchPlan fp = getPM().getFetchPlan();
    fp.setGroups(expectedGroups);
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkSetGroupsCollection(): wrong getGroups() " + "after SetGroups(Collection).",
          expectedGroups,
          groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  public void checkSetGroupsArray() {
    Set<String> expectedGroups = new HashSet<>();
    expectedGroups.add("default");
    expectedGroups.add("group1");
    expectedGroups.add("group2");
    FetchPlan fp = getPM().getFetchPlan();
    fp.setGroups("default", "group1", "group2");
    Collection<String> groups = fp.getGroups();
    if (!setEquals(expectedGroups, groups)) {
      failCompare(
          "checkSetGroupsArray(): wrong getGroups() " + "after setGroups(String[]).",
          expectedGroups,
          groups);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  protected void checkGetDetachmentRoots() {
    Set<String> expectedRoots = new HashSet<>();
    FetchPlan fp = getPM().getFetchPlan();
    Collection<String> roots = fp.getDetachmentRoots();
    if (!setEquals(expectedRoots, roots)) {
      failCompare(
          "checkGetDetachmentRoots(): wrong getDetachmentRoots() "
              + "after getPersistenceManager().",
          expectedRoots,
          roots);
    }
    cleanupPM();
  }

  /** */
  @SuppressWarnings("unchecked")
  protected void checkSetDetachmentRoots() {
    PCPoint p = new PCPoint(10, 20);
    Set<PCPoint> expectedRoots = new HashSet<>();
    expectedRoots.add(p);
    FetchPlan fp = getPM().getFetchPlan();
    fp.setDetachmentRoots(expectedRoots);
    Collection<PCPoint> roots = fp.getDetachmentRoots();
    if (!setEquals(expectedRoots, roots)) {
      failCompare(
          "checkGetDetachmentRoots(): wrong getDetachmentRoots() " + "after setDetachmentRoots().",
          expectedRoots,
          roots);
    }
    cleanupPM();
  }

  /** */
  private void checkSetDetachmentRootClasses() {
    @SuppressWarnings("rawtypes")
    Class<?>[] expectedRootClasses = new Class[] {PCPoint.class};
    FetchPlan fp = getPM().getFetchPlan();
    fp.setDetachmentRootClasses(expectedRootClasses);
    Class<?>[] rootClasses = fp.getDetachmentRootClasses();
    if (!Arrays.equals(expectedRootClasses, rootClasses)) {
      failCompare(
          "checkGetDetachmentRootClasses(): "
              + "wrong getDetachmentRootClasses() "
              + "after setDetachmentRootClasses().",
          expectedRootClasses,
          rootClasses);
    }
    cleanupPM();
  }
}
