/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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 junit.framework;

// Note: this class was written without inspecting the junit.framework code

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;
import vogar.target.junit.Junit3;

public class TestSuite implements Test {
    /** A heterogeneous list containing of tests and test classes. */
    private final List<Object> testsAndSuites = new ArrayList<Object>();
    private final String name;

    public TestSuite() {
        this.name = null;
    }

    public TestSuite(String name) {
        this.name = name;
    }

    public TestSuite(Class<?> suite) {
        this(suite, null);
    }

    public TestSuite(Class<?> suite, String name) {
        if (suite == null) {
            throw new IllegalArgumentException("suite == null");
        }
        testsAndSuites.add(suite);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void addTest(Test test) {
        if (!(test instanceof TestCase) && !(test instanceof TestSuite)) {
            throw new IllegalArgumentException("Unexpected test: " + test);
        }
        testsAndSuites.add(test);
    }
    
    public void addTestSuite(Class<?> suite) {
        testsAndSuites.add(suite);
    }

    @Override
    public int countTestCases() {
        return testsAndSuites.size();
    }

    @Override
    public void run(TestResult result) {
        throw new UnsupportedOperationException();
    }

    /**
     * The official JUnit framework creates test instances eagerly and holds
     * them for the duration of the test run. We prefer to create tests lazily,
     * and release them after use. Unfortunately, calls to this method require
     * us to fall back to JUnit-style eager creation. This method should only be
     * used by framework code.
     */
    public Enumeration<?> tests() {
        for (ListIterator<Object> i = testsAndSuites.listIterator(); i.hasNext(); ) {
            Object o = i.next();
            if (o instanceof Class) {
                i.remove();
                for (Test test : Junit3.classToJunitTests((Class<?>) o)) {
                    i.add(test);
                }
            }
        }
        return Collections.enumeration(testsAndSuites);
    }

    public final List<Object> getTestsAndSuites() {
        return testsAndSuites;
    } 
}
