/*
 * 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.sling.testing.mock.sling.junit;

import java.util.Map;

import org.apache.sling.testing.mock.osgi.context.ContextCallback;
import org.apache.sling.testing.mock.osgi.context.ContextPlugins;
import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.context.SlingContextImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.rules.ExternalResource;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.osgi.annotation.versioning.ProviderType;

/**
 * JUnit rule for setting up and tearing down Sling context objects for unit tests.
 * You can use {@link SlingContextBuilder} alternatively to the constructors on this class - it offers
 * more options and fine-grained control about setting up the test context.
 */
@ProviderType
public final class SlingContext extends SlingContextImpl implements TestRule {

    private final ContextPlugins plugins;
    private final TestRule delegate;

    /**
     * Initialize Sling context with default resource resolver type:
     * {@link org.apache.sling.testing.mock.sling.MockSling#DEFAULT_RESOURCERESOLVER_TYPE}.
     */
    public SlingContext() {
        this(new ContextPlugins(), null, null);
    }

    /**
     * Initialize Sling context with resource resolver type.
     * @param resourceResolverType Resource resolver type.
     */
    public SlingContext(@NotNull final ResourceResolverType resourceResolverType) {
        this(new ContextPlugins(), null, resourceResolverType);
    }

    /**
     * Initialize Sling context with default resource resolver type:
     * {@link org.apache.sling.testing.mock.sling.MockSling#DEFAULT_RESOURCERESOLVER_TYPE}.
     * @param <T> context type
     * @param afterSetUpCallback Allows the application to register an own callback function that is called after the built-in setup rules are executed.
     */
    public <T extends OsgiContextImpl> SlingContext(@NotNull final ContextCallback<T> afterSetUpCallback) {
        this(new ContextPlugins(afterSetUpCallback), null, null);
    }

    /**
     * Initialize Sling context with resource resolver type.
     * @param <T> context type
     * @param afterSetUpCallback Allows the application to register an own callback function that is called after the built-in setup rules are executed.
     * @param resourceResolverType Resource resolver type.
     */
    public <T extends OsgiContextImpl> SlingContext(@NotNull final ContextCallback<T> afterSetUpCallback, @NotNull final ResourceResolverType resourceResolverType) {
        this(new ContextPlugins(afterSetUpCallback), null, resourceResolverType);
    }

    /**
     * Initialize Sling context with default resource resolver type:
     * {@link org.apache.sling.testing.mock.sling.MockSling#DEFAULT_RESOURCERESOLVER_TYPE}.
     * @param <U> context type
     * @param <V> context type
     * @param afterSetUpCallback Allows the application to register an own callback function that is called after the built-in setup rules are executed.
     * @param beforeTearDownCallback Allows the application to register an own callback function that is called before the built-in teardown rules are executed.
     */
    public <U extends OsgiContextImpl, V extends OsgiContextImpl> SlingContext(@NotNull final ContextCallback<U> afterSetUpCallback,
            @NotNull final ContextCallback<V> beforeTearDownCallback) {
        this(new ContextPlugins(afterSetUpCallback, beforeTearDownCallback), null, null);
    }
    
    /**
     * Initialize Sling context with resource resolver type.
     * @param <U> context type
     * @param <V> context type
     * @param afterSetUpCallback Allows the application to register an own callback function that is called after the built-in setup rules are executed.
     * @param beforeTearDownCallback Allows the application to register an own callback function that is called before the built-in teardown rules are executed.
     * @param resourceResolverType Resource resolver type.
     */
    public <U extends OsgiContextImpl, V extends OsgiContextImpl> SlingContext(@NotNull final ContextCallback<U> afterSetUpCallback,
            @NotNull final ContextCallback<V> beforeTearDownCallback,
            @NotNull final ResourceResolverType resourceResolverType) {
        this(new ContextPlugins(afterSetUpCallback, beforeTearDownCallback), null, resourceResolverType);
    }
    
    /**
     * Initialize Sling context with resource resolver type.
     * @param contextPlugins Context plugins
     * @param resourceResolverFactoryActivatorProps Allows to override OSGi configuration parameters for the Resource Resolver Factory Activator service.
     * @param resourceResolverType Resource resolver type.
     */
    SlingContext(@NotNull final ContextPlugins contextPlugins,
            @Nullable final Map<String, Object> resourceResolverFactoryActivatorProps,
            @Nullable final ResourceResolverType resourceResolverType) {
        this(contextPlugins, resourceResolverFactoryActivatorProps, resourceResolverType, true);
    }

    /**
     * Initialize Sling context with resource resolver type.
     * @param contextPlugins Context plugins
     * @param resourceResolverFactoryActivatorProps Allows to override OSGi configuration parameters for the Resource Resolver Factory Activator service.
     * @param resourceResolverType Resource resolver type.
     * @param registerSlingModelsFromClassPath Automatic registering of all Sling Models found in the classpath on startup.
     */
    SlingContext(@NotNull final ContextPlugins contextPlugins,
            @Nullable final Map<String, Object> resourceResolverFactoryActivatorProps,
            @Nullable final ResourceResolverType resourceResolverType,
            final boolean registerSlingModelsFromClassPath) {

        this.plugins = contextPlugins;
        setResourceResolverFactoryActivatorProps(resourceResolverFactoryActivatorProps);
        setRegisterSlingModelsFromClassPath(registerSlingModelsFromClassPath);

        // set resource resolver type in parent context
        setResourceResolverType(resourceResolverType);

        // wrap {@link ExternalResource} rule executes each test method once
        this.delegate = new ExternalResource() {
            @Override
            protected void before() {
                plugins.executeBeforeSetUpCallback(SlingContext.this);
                SlingContext.this.setUp();
                plugins.executeAfterSetUpCallback(SlingContext.this);
            }

            @Override
            protected void after() {
                plugins.executeBeforeTearDownCallback(SlingContext.this);
                SlingContext.this.tearDown();
                plugins.executeAfterTearDownCallback(SlingContext.this);
            }
        };
    }

    @Override
    public Statement apply(final Statement base, final Description description) {
        return this.delegate.apply(base, description);
    }

}
