/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.transparentindirection;

import java.util.*;
import java.lang.reflect.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * provide support for zunit stuff...
 */
public class ZTestSuite extends TestSuite {
    public ZTestSuite() {
        this("Unnamed Test Suite");
    }

    public ZTestSuite(Class testCaseClass) {
        this(testCaseClass.getName(), testCaseClass);
    }

    public ZTestSuite(String name) {
        super();
        this.setName(name);
    }

    public ZTestSuite(String name, Class testCaseClass) {
        this(name);
        this.add(testCaseClass);
    }

    public void add(Class testCaseClass) {
        Constructor ctor = this.singleArgumentConstructorFor(testCaseClass);
        Object[] arguments = new Object[1];

        Enumeration enumtr = this.methodNamesStartingWithTestFor(testCaseClass);
        while (enumtr.hasMoreElements()) {
            try {
                arguments[0] = enumtr.nextElement();
                this.addTest((ZTestCase)ctor.newInstance(arguments));
            } catch (IllegalAccessException iae) {
                throw new RuntimeException("The constructor \"" + ctor + "\" (and its class) must be public.");
            } catch (InvocationTargetException ite) {
                throw new RuntimeException("The constructor \"" + ctor + "\" threw an exception during invocation: " + ite.getTargetException());
            } catch (InstantiationException ie) {
                throw new RuntimeException("The constructor \"" + ctor + "\" was unable to instantiate an instance....");
            }
        }
    }

    /**
     * Return an enumeration on all the method names for the
     * specified class that begin with "test", removing any duplicates.
     * @param testClass a subclass of <code>TestCase</code>
     */
    public Enumeration methodNamesStartingWithTestFor(Class testClass) {
        Method[] methods = testClass.getMethods();
        Vector names = new Vector(methods.length);
        for (int i = 0; i < methods.length; i++) {
            String name = methods[i].getName();
            if (name.startsWith("test")) {
                names.addElement(name);
            }
        }
        Hashtable uniqueNames = new Hashtable();
        for (Enumeration e = names.elements(); e.hasMoreElements();) {
            Object name = e.nextElement();
            uniqueNames.put(name, name);// use the Hashtable as a Set
        }
        return uniqueNames.elements();
    }

    /**
     * Return the required constructor for the specified class.
     * @param testCaseClass a subclass of <code>TestCase</code>
     */
    private Constructor singleArgumentConstructorFor(Class testCaseClass) {
        try {
            return testCaseClass.getConstructor(new Class[] { String.class });
        } catch (NoSuchMethodException e) {
            String name = testCaseClass.getName();
            throw new RuntimeException("The class '" + name + "' must implement the constructor '" + name + "(String)'");
        }
    }
}
