/*
 * 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.context;

import static org.apache.sling.testing.mock.sling.context.MockSlingBindings.SERVICE_PROPERTY_MOCK_SLING_BINDINGS_IGNORE;
import static org.osgi.service.event.EventConstants.EVENT_TOPIC;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.featureflags.impl.FeatureManager;
import org.apache.sling.jcr.resource.internal.scripting.JcrObjectsBindingsValuesProvider;
import org.apache.sling.models.impl.ModelAdapterFactory;
import org.apache.sling.resourcebuilder.api.ResourceBuilder;
import org.apache.sling.resourcebuilder.api.ResourceBuilderFactory;
import org.apache.sling.resourcebuilder.impl.ResourceBuilderFactoryService;
import org.apache.sling.scripting.core.impl.BindingsValuesProvidersByContextImpl;
import org.apache.sling.settings.SlingSettingsService;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
import org.apache.sling.testing.mock.sling.MockResourceBundleProvider;
import org.apache.sling.testing.mock.sling.MockSling;
import org.apache.sling.testing.mock.sling.MockXSSFilter;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.builder.ContentBuilder;
import org.apache.sling.testing.mock.sling.loader.ContentLoader;
import org.apache.sling.testing.mock.sling.services.MockMimeTypeService;
import org.apache.sling.testing.mock.sling.services.MockSlingSettingService;
import org.apache.sling.testing.mock.sling.servlet.MockRequestPathInfo;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.apache.sling.xss.impl.XSSAPIImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ConsumerType;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.EventHandler;

/**
 * Defines Sling context objects with lazy initialization.
 * Should not be used directly but via the SlingContext JUnit rule or extension.
 */
@ConsumerType
public class SlingContextImpl extends OsgiContextImpl {

    static {
        // ugly hack: prevent default console logging from ESAPI on each initialization by setting system property
        System.setProperty("org.owasp.esapi.logSpecial.discard", "true");
    }

    // default to publish instance run mode
    static final @NotNull Set<String> DEFAULT_RUN_MODES = Collections.singleton("publish");

    private static final @NotNull String RESOURCERESOLVERFACTORYACTIVATOR_PID = "org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl";

    /**
     * Resource resolver factory
     */
    protected ResourceResolverFactory resourceResolverFactory;

    /**
     * Resource resolver type
     */
    protected ResourceResolverType resourceResolverType;

    /**
     * Resource resolver
     */
    protected ResourceResolver resourceResolver;

    /**
     * Sling request
     */
    protected MockSlingHttpServletRequest request;

    /**
     * Sling response
     */
    protected MockSlingHttpServletResponse response;

    /**
     * Sling script helper
     */
    protected SlingScriptHelper slingScriptHelper;

    /**
     * Content loader
     */
    protected ContentLoader contentLoader;

    /**
     * Content loader with auto commit after loading content
     */
    protected ContentLoader contentLoaderAutoCommit;

    /**
     * Content builder
     */
    protected ContentBuilder contentBuilder;

    /**
     * Resource builder
     */
    protected ResourceBuilder resourceBuilder;

    /**
     * Unique root helper
     */
    protected UniqueRoot uniqueRoot;

    private Map<String, Object> resourceResolverFactoryActivatorProps;
    private boolean registerSlingModelsFromClassPath = true;

    /**
     * @param resourceResolverType Resource resolver type
     */
    protected void setResourceResolverType(@Nullable final ResourceResolverType resourceResolverType) {
        if (resourceResolverType == null) {
            this.resourceResolverType = MockSling.DEFAULT_RESOURCERESOLVER_TYPE;
        }
        else {
            this.resourceResolverType = resourceResolverType;
        }
    }

    /**
     * @param props Resolver resolver factory activator properties
     */
    protected void setResourceResolverFactoryActivatorProps(@Nullable Map<String, Object> props) {
        this.resourceResolverFactoryActivatorProps = props;
    }

    /**
     * @param registerSlingModelsFromClassPath Register sling models from classpath
     */
    protected void setRegisterSlingModelsFromClassPath(boolean registerSlingModelsFromClassPath) {
        this.registerSlingModelsFromClassPath = registerSlingModelsFromClassPath;
    }

    /**
     * Setup actions before test method execution
     */
    @Override
    protected void setUp() {
        super.setUp();
        MockSling.setAdapterManagerBundleContext(bundleContext());

        if (this.resourceResolverFactoryActivatorProps != null) {
            // use OSGi ConfigurationAdmin to pass over customized configuration to Resource Resolver Factory Activator service
            MockOsgi.setConfigForPid(bundleContext(), RESOURCERESOLVERFACTORYACTIVATOR_PID, this.resourceResolverFactoryActivatorProps);
        }

        // automatically register resource resolver factory when ResourceResolverType != NONE,
        // so the ResourceResolverFactory is available as OSGi service immediately
        if (resourceResolverType != ResourceResolverType.NONE) {
            resourceResolverFactory();
        }

        registerDefaultServices();
    }

    /**
     * Initialize mocked resource resolver factory.
     * @return Resource resolver factory
     */
    protected @NotNull ResourceResolverFactory newResourceResolverFactory() {
        return ContextResourceResolverFactory.get(this.resourceResolverType, bundleContext());
    }

    private @NotNull ResourceResolverFactory resourceResolverFactory() {
        if (this.resourceResolverFactory == null) {
            this.resourceResolverFactory = newResourceResolverFactory();
        }
        return this.resourceResolverFactory;
    }

    /**
     * Default services that should be available for every unit test
     */
    protected void registerDefaultServices() {

        // scripting services (required by sling models impl since 1.3.6)
        registerInjectActivateServiceByClassName(
                "org.apache.sling.scripting.core.impl.ScriptEngineManagerFactory",
                "org.apache.sling.scripting.core.impl.jsr223.SlingScriptEngineManager");
        registerInjectActivateService(new BindingsValuesProvidersByContextImpl());

        // sling models
        registerInjectActivateService(new ModelAdapterFactory());
        registerInjectActivateServiceByClassName(
                "org.apache.sling.models.impl.FirstImplementationPicker",
                "org.apache.sling.models.impl.ResourceTypeBasedResourcePicker",
                "org.apache.sling.models.impl.injectors.BindingsInjector",
                "org.apache.sling.models.impl.injectors.ChildResourceInjector",
                "org.apache.sling.models.impl.injectors.OSGiServiceInjector",
                "org.apache.sling.models.impl.injectors.RequestAttributeInjector",
                "org.apache.sling.models.impl.injectors.ResourcePathInjector",
                "org.apache.sling.models.impl.injectors.SelfInjector",
                "org.apache.sling.models.impl.injectors.SlingObjectInjector",
                "org.apache.sling.models.impl.injectors.ValueMapInjector",
                "org.apache.sling.models.impl.via.BeanPropertyViaProvider",
                "org.apache.sling.models.impl.via.ChildResourceViaProvider",
                "org.apache.sling.models.impl.via.ForcedResourceTypeViaProvider",
                "org.apache.sling.models.impl.via.ResourceSuperTypeViaProvider");

        // other services
        registerService(SlingSettingsService.class, new MockSlingSettingService(DEFAULT_RUN_MODES));
        registerService(MimeTypeService.class, new MockMimeTypeService());
        registerInjectActivateService(new ResourceBuilderFactoryService());
        registerInjectActivateService(new JcrObjectsBindingsValuesProvider(),
                SERVICE_PROPERTY_MOCK_SLING_BINDINGS_IGNORE, true);
        registerInjectActivateService(new MockResourceBundleProvider());
        registerInjectActivateService(MockXSSFilter.class);
        registerInjectActivateService(XSSAPIImpl.class);
        registerInjectActivateService(new FeatureManager());

        // scan for models defined via bundle headers in classpath
        if (registerSlingModelsFromClassPath) {
            ModelAdapterFactoryUtil.addModelsForManifestEntries(this.bundleContext());
        }
    }

    @SuppressWarnings("null")
    private void registerInjectActivateServiceByClassName(@NotNull String @NotNull ... classNames) {
        for (String className : classNames) {
            try {
                Class<?> clazz = Class.forName(className);
                registerInjectActivateService(clazz.newInstance());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                // ignore - probably not the latest sling models impl version
            }
        }
    }

    /**
     * Teardown actions after test method execution
     */
    @Override
    protected void tearDown() {

        if (this.request != null) {
            SlingBindings slingBindings = (SlingBindings)this.request.getAttribute(SlingBindings.class.getName());
            if (slingBindings instanceof MockSlingBindings) {
                ((MockSlingBindings)slingBindings).tearDown();
            }
        }

        if (this.resourceResolver != null) {

            // revert potential unsaved changes in resource resolver/JCR session
            try {
                this.resourceResolver.revert();
            } catch (UnsupportedOperationException ex){
                // ignore - this may happen when jcr-mock is used
            }
            Session session = this.resourceResolver.adaptTo(Session.class);
            if (session != null) {
                try {
                    session.refresh(false);
                } catch (RepositoryException ex) {
                    // ignore
                } catch (UnsupportedOperationException ex){
                    // ignore - this may happen when jcr-mock is used
                }
            }

            // remove unique roots
            if (this.uniqueRoot != null) {
                this.uniqueRoot.cleanUp();
            }

            // close resource resolver
            this.resourceResolver.close();
        }

        this.resourceResolver = null;
        this.request = null;
        this.response = null;
        this.slingScriptHelper = null;
        this.contentLoader = null;
        this.contentLoaderAutoCommit = null;
        this.contentBuilder = null;
        this.resourceBuilder = null;
        this.uniqueRoot = null;
        this.resourceResolverFactory = null;

        super.tearDown();

        MockSling.clearAdapterManagerBundleContext();
    }

    /**
     * @return Resource resolver type
     */
    public final @NotNull ResourceResolverType resourceResolverType() {
        return this.resourceResolverType;
    }

    /**
     * Returns the singleton resource resolver bound to this context.
     * It is automatically closed after the test.
     * @return Resource resolver
     */
    @SuppressWarnings("deprecation")
    public final @NotNull ResourceResolver resourceResolver() {
        if (this.resourceResolver == null) {
            try {
                this.resourceResolver = this.resourceResolverFactory().getAdministrativeResourceResolver(null);
            } catch (LoginException ex) {
                throw new RuntimeException("Creating resource resolver failed.", ex);
            }
        }
        return this.resourceResolver;
    }

    /**
     * @return Sling request
     */
    public final @NotNull MockSlingHttpServletRequest request() {
        if (this.request == null) {
            this.request = new MockSlingHttpServletRequest(this.resourceResolver(), this.bundleContext());

            // initialize sling bindings
            MockSlingBindings bindings = new MockSlingBindings(this);

            // register as OSGi event handler to get notified on events fired by BindingsValuesProvidersByContextImpl
            this.registerService(EventHandler.class, bindings,
                    EVENT_TOPIC, "org/apache/sling/scripting/core/BindingsValuesProvider/*");

            this.request.setAttribute(SlingBindings.class.getName(), bindings);
        }
        return this.request;
    }

    /**
     * Dynamically resolve property request for current request {@link SlingBindings}.
     * @param property Property key
     * @param request Context request
     * @return Resolved object or null if no result found
     */
    protected @Nullable Object resolveSlingBindingProperty(@NotNull String property, @NotNull SlingHttpServletRequest request) {
        return MockSlingBindings.resolveSlingBindingProperty(this, property);
    }

    /**
     * Dynamically resolve property request for current request {@link SlingBindings}.
     * @param property Property key
     * @return Resolved object or null if no result found
     * @deprecated Please use {@link #resolveSlingBindingProperty(String, SlingHttpServletRequest)}
     */
    @Deprecated
    protected @Nullable Object resolveSlingBindingProperty(@NotNull String property) {
        return MockSlingBindings.resolveSlingBindingProperty(this, property);
    }

    /**
     * @return Request path info
     */
    public final @NotNull MockRequestPathInfo requestPathInfo() {
        return (MockRequestPathInfo)request().getRequestPathInfo();
    }

    /**
     * @return Sling response
     */
    public final @NotNull MockSlingHttpServletResponse response() {
        if (this.response == null) {
            this.response = new MockSlingHttpServletResponse();
        }
        return this.response;
    }

    /**
     * @return Sling script helper
     */
    public final @NotNull SlingScriptHelper slingScriptHelper() {
        if (this.slingScriptHelper == null) {
            this.slingScriptHelper = MockSling.newSlingScriptHelper(this.request(), this.response(),
                    this.bundleContext());
        }
        return this.slingScriptHelper;
    }

    /**
     * @return Content loader
     */
    public @NotNull ContentLoader load() {
        return load(true);
    }

    /**
     * @param autoCommit Automatically commit changes after loading content (default: true)
     * @return Content loader
     */
    public @NotNull ContentLoader load(boolean autoCommit) {
        if (autoCommit) {
            if (this.contentLoaderAutoCommit == null) {
                this.contentLoaderAutoCommit = new ContentLoader(resourceResolver(), bundleContext(), true, this.resourceResolverType());
            }
            return this.contentLoaderAutoCommit;
        }
        else {
            if (this.contentLoader == null) {
                this.contentLoader = new ContentLoader(resourceResolver(), bundleContext(), false, this.resourceResolverType());
            }
            return this.contentLoader;
        }
    }

    /**
     * Creates a {@link ContentBuilder} object for easily creating test content.
     * This API was part of Sling Mocks since version 1.x.
     * You can use alternatively the {@link #build()} method and use the {@link ResourceBuilder} API.
     * @return Content builder for building test content
     */
    public @NotNull ContentBuilder create() {
        if (this.contentBuilder == null) {
            this.contentBuilder = new ContentBuilder(resourceResolver());
        }
        return this.contentBuilder;
    }

    /**
     * Creates a {@link ResourceBuilder} object for easily creating test content.
     * This is a separate API which can be used inside sling mocks or in a running instance.
     * You can use alternatively the {@link #create()} method to use the {@link ContentBuilder} API.
     * @return Resource builder for building test content.
     */
    @SuppressWarnings("null")
    public @NotNull ResourceBuilder build() {
        if (this.resourceBuilder == null) {
            this.resourceBuilder = getService(ResourceBuilderFactory.class).forResolver(this.resourceResolver());
        }
        return this.resourceBuilder;
    }

    /**
     * @return Current resource
     */
    public final @Nullable Resource currentResource() {
        return request().getResource();
    }

    /**
     * Set current resource in request.
     * @param resourcePath Resource path
     * @return Current resource
     */
    public final @Nullable Resource currentResource(@Nullable String resourcePath) {
        if (resourcePath != null) {
            Resource resource = resourceResolver().getResource(resourcePath);
            if (resource == null) {
                throw new IllegalArgumentException("Resource does not exist: " + resourcePath);
            }
            return currentResource(resource);
        } else {
            return currentResource((Resource)null);
        }
    }

    /**
     * Set current resource in request.
     * @param resource Resource
     * @return Current resource
     */
    public @Nullable Resource currentResource(@Nullable Resource resource) {
        request().setResource(resource);
        return resource;
    }

    /**
     * Search classpath for given java package names (and sub packages) to scan for and
     * register all classes with @Model annotation.
     * @param packageName Java package name
     */
    public final void addModelsForPackage(@NotNull String packageName) {
        ModelAdapterFactoryUtil.addModelsForPackages(bundleContext(),  packageName);
    }

    /**
     * Search classpath for given java package names (and sub packages) to scan for and
     * register all classes with @Model annotation.
     * @param packageNames Java package names
     */
    public final void addModelsForPackage(@NotNull String @NotNull ... packageNames) {
        ModelAdapterFactoryUtil.addModelsForPackages(bundleContext(), packageNames);
    }

    /**
     * Search classpath for given class names to scan for and register all classes with @Model annotation.
     * @param classNames Java class names
     */
    public final void addModelsForClasses(@NotNull String @NotNull ... classNames) {
        ModelAdapterFactoryUtil.addModelsForClasses(bundleContext(), classNames);
    }

    /**
     * Search classpath for given class names to scan for and register all classes with @Model annotation.
     * @param classes Java classes
     */
    public final void addModelsForClasses(@NotNull Class @NotNull ... classes) {
        ModelAdapterFactoryUtil.addModelsForClasses(bundleContext(), classes);
    }

    /**
     * Set current run mode(s).
     * @param runModes Run mode(s).
     */
    @SuppressWarnings("null")
    public final void runMode(@NotNull String @NotNull ... runModes) {
        Set<String> newRunModes = new HashSet<>(Arrays.asList(runModes));
        ServiceReference<SlingSettingsService> ref = bundleContext().getServiceReference(SlingSettingsService.class);
        if (ref != null) {
            MockSlingSettingService slingSettings = (MockSlingSettingService)bundleContext().getService(ref);
            slingSettings.setRunModes(newRunModes);
        }
    }

    /**
     * Create unique root paths for unit tests (and clean them up after the test run automatically).
     * @return Unique root path helper
     */
    public @NotNull UniqueRoot uniqueRoot() {
        if (uniqueRoot == null) {
            uniqueRoot = new UniqueRoot(this);
        }
        return uniqueRoot;
    }

    /**
     * Create a Sling AdapterFactory on the fly which can adapt from <code>adaptableClass</code>
     * to <code>adapterClass</code> and just returns the given value as result.
     * @param adaptableClass Class to adapt from
     * @param adapterClass Class to adapt to
     * @param adapter Object which is always returned for this adaption.
     * @param <T1> Adaptable type
     * @param <T2> Adapter type
     */
    public final <T1, T2> void registerAdapter(@NotNull final Class<T1> adaptableClass, @NotNull final Class<T2> adapterClass,
            @NotNull final T2 adapter) {
        registerAdapter(adaptableClass, adapterClass, new Function<T1, T2>() {
            @Override
            public T2 apply(@Nullable T1 input) {
                return adapter;
            }
        });
    }

    /**
     * Create a Sling AdapterFactory on the fly which can adapt from <code>adaptableClass</code>
     * to <code>adapterClass</code> and delegates the adapter mapping to the given <code>adaptHandler</code> function.
     * @param adaptableClass Class to adapt from
     * @param adapterClass Class to adapt to
     * @param adaptHandler Function to handle the adaption
     * @param <T1> Adaptable type
     * @param <T2> Adapter type
     */
    public final <T1, T2> void registerAdapter(@NotNull final Class<T1> adaptableClass, @NotNull final Class<T2> adapterClass,
            @NotNull final Function<T1,T2> adaptHandler) {
        AdapterFactory adapterFactory = new AdapterFactory() {
            @SuppressWarnings("unchecked")
            @Override
            public <AdapterType> AdapterType getAdapter(@NotNull Object adaptable, @NotNull Class<AdapterType> type) {
                return (AdapterType)adaptHandler.apply((T1)adaptable);
            }
        };
        Map<String,Object> props = new HashMap<>();
        props.put(AdapterFactory.ADAPTABLE_CLASSES, new String[] {
                adaptableClass.getName()
            });
        props.put(AdapterFactory.ADAPTER_CLASSES, new String[] {
                adapterClass.getName()
            });
        // make sure this overlay has higher ranking than other adapter factories
        // normally we should use Integer.MAX_VALUE for this - but due to SLING-7194 prefers lowest-ranking services first
        props.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
        registerService(AdapterFactory.class, adapterFactory, props);
    }

}
