/*
 * 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.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 boolean setEquals
            (Collection expected, Collection actual) {
        if (expected == actual) 
            return true;
        if (expected == null || actual == null) 
            return false;
        Set expectedSet = new HashSet(expected);
        Set 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();
    }

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

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

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

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

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

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

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

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

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

    /** */
    private void checkSetDetachmentRootClasses() {
        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();
    }

}
