// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.base.test.util;

import static org.hamcrest.Matchers.isIn;
import static org.junit.Assert.fail;

import android.app.Instrumentation;
import android.content.Context;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;

import org.junit.Assert;
import org.junit.rules.ExternalResource;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.robolectric.RuntimeEnvironment;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * Helper rule to allow executing test runners in tests.
 *
 * Quis probat ipsas probas?
 */
class TestRunnerTestRule extends ExternalResource {
    final Class<? extends BlockJUnit4ClassRunner> mRunnerClass;

    /**
     * @param runnerClass The runner class to run the test
     */
    TestRunnerTestRule(Class<? extends BlockJUnit4ClassRunner> runnerClass) {
        mRunnerClass = runnerClass;
    }

    @Override
    protected void before() throws Throwable {
        // Register a fake Instrumentation so that class runners for instrumentation tests
        // can be run even in Robolectric tests.
        Instrumentation instrumentation = new Instrumentation() {
            @Override
            public Context getTargetContext() {
                return RuntimeEnvironment.application;
            }
        };
        InstrumentationRegistry.registerInstance(instrumentation, new Bundle());
    }

    @Override
    protected void after() {
        InstrumentationRegistry.registerInstance(null, new Bundle());
    }

    /**
     * A struct-like class containing lists of run and skipped tests.
     */
    public static class TestLog {
        public final List<Description> runTests = new ArrayList<>();
        public final List<Description> skippedTests = new ArrayList<>();
    }

    /**
     * Creates a new test runner and executes the test in the given {@code testClass} on it,
     * returning lists of tests that were run and tests that were skipped.
     * @param testClass The test class
     * @return A {@link TestLog} that contains lists of run and skipped tests.
     */
    public TestLog runTest(Class<?> testClass) throws InvocationTargetException,
                                                      NoSuchMethodException, InstantiationException,
                                                      IllegalAccessException {
        TestLog testLog = new TestLog();

        // TODO(bauerb): Using Mockito mock() or spy() throws a ClassCastException.
        RunListener runListener = new RunListener() {
            @Override
            public void testStarted(Description description) throws Exception {
                testLog.runTests.add(description);
            }

            @Override
            public void testFinished(Description description) throws Exception {
                Assert.assertThat(description, isIn(testLog.runTests));
            }

            @Override
            public void testFailure(Failure failure) throws Exception {
                fail(failure.toString());
            }

            @Override
            public void testAssumptionFailure(Failure failure) {
                fail(failure.toString());
            }

            @Override
            public void testIgnored(Description description) throws Exception {
                testLog.skippedTests.add(description);
            }
        };
        RunNotifier runNotifier = new RunNotifier();
        runNotifier.addListener(runListener);
        Runner runner;
        try {
            runner = mRunnerClass.getConstructor(Class.class).newInstance(testClass);
        } catch (InvocationTargetException e) {
            // If constructing the runner caused initialization errors, unwrap them from the
            // InvocationTargetException.
            Throwable cause = e.getCause();
            if (!(cause instanceof InitializationError)) throw e;
            List<Throwable> causes = ((InitializationError) cause).getCauses();

            // If there was exactly one initialization error, rewrap that one.
            if (causes.size() == 1) {
                throw new InvocationTargetException(causes.get(0), "Initialization error");
            }

            // Otherwise, serialize all initialization errors to a string and throw that.
            throw new AssertionError(causes.toString());
        }
        runner.run(runNotifier);
        return testLog;
    }
}
