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

import java.io.IOException;
import java.util.Dictionary;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.log.LogService;

import static org.apache.sling.testing.mock.osgi.MapMergeUtil.propertiesMergeWithOsgiMetadata;
import static org.apache.sling.testing.mock.osgi.MapUtil.toDictionary;
import static org.apache.sling.testing.mock.osgi.MapUtil.toMap;

/**
 * Factory for mock OSGi objects.
 */
public final class MockOsgi {

    private MockOsgi() {
        // static methods only
    }

    /**
     * @return Mocked {@link BundleContext} instance
     */
    public static @NotNull BundleContext newBundleContext() {
        return new MockBundleContext();
    }

    /**
     * Simulates a bundle event on the given bundle context (that is forwarded
     * to registered bundle listeners).
     * @param bundleContext Bundle context
     * @param bundleEvent Bundle event
     */
    public static void sendBundleEvent(@NotNull BundleContext bundleContext, @NotNull BundleEvent bundleEvent) {
        ((MockBundleContext) bundleContext).sendBundleEvent(bundleEvent);
    }

    /**
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext() {
        return componentContext().build();
    }

    /**
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(@Nullable Dictionary<String, Object> properties) {
        return componentContext().properties(properties).build();
    }

    /**
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(@Nullable Map<String, Object> properties) {
        return componentContext().properties(properties).build();
    }

    /**
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(@NotNull Object @NotNull ... properties) {
        return componentContext().properties(properties).build();
    }

    /**
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(
            @NotNull BundleContext bundleContext, @Nullable Dictionary<String, Object> properties) {
        return componentContext()
                .bundleContext(bundleContext)
                .properties(properties)
                .build();
    }

    /**
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(
            @NotNull BundleContext bundleContext, @Nullable Map<String, Object> properties) {
        return componentContext()
                .bundleContext(bundleContext)
                .properties(properties)
                .build();
    }

    /**
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return Mocked {@link ComponentContext} instance
     */
    public static @NotNull ComponentContext newComponentContext(
            @NotNull BundleContext bundleContext, @NotNull Object @NotNull ... properties) {
        return componentContext()
                .bundleContext(bundleContext)
                .properties(properties)
                .build();
    }

    /**
     * @return {@link ComponentContextBuilder} to build a mocked {@link ComponentContext}
     */
    public static @NotNull ComponentContextBuilder componentContext() {
        return new ComponentContextBuilder();
    }

    /**
     * @param loggerContext Context class for logging
     * @return Mocked {@link LogService} instance
     */
    public static @NotNull LogService newLogService(@NotNull final Class<?> loggerContext) {
        return new MockLogService(loggerContext);
    }

    /**
     * Simulates OSGi DS dependency injection. Injects direct references and multiple references.
     * If a some references could not be injected no error is thrown.
     * @param target Service instance
     * @param bundleContext Bundle context from which services are fetched to inject.
     * @return true if all dependencies could be injected, false if the service has no dependencies.
     */
    public static boolean injectServices(@NotNull Object target, @NotNull BundleContext bundleContext) {
        return MockOsgi.injectServices(target, bundleContext, (Map<String, Object>) null);
    }

    /**
     * Simulates OSGi DS dependency injection. Injects direct references and multiple references.
     * If a some references could not be injected no error is thrown.
     * @param target Service instance
     * @param bundleContext Bundle context from which services are fetched to inject.
     * @param properties Service properties (used to resolve dynamic reference properties)
     * @return true if all dependencies could be injected, false if the service has no dependencies.
     */
    public static boolean injectServices(
            @NotNull Object target, @NotNull BundleContext bundleContext, @Nullable Map<String, Object> properties) {
        return OsgiServiceUtil.injectServices(target, bundleContext, properties);
    }

    /**
     * Simulates OSGi DS dependency injection and activation. Injects direct references and multiple references.
     * If a some references could not be injected no error is thrown.
     * This method instantiates the service instance and also supports constructor injection.
     * @param targetClass Component/service class
     * @param bundleContext Bundle context from which services are fetched to inject.
     * @param <T> Target class type
     * @return Component/service instances with injected services
     */
    public static @NotNull <T> T activateInjectServices(
            @NotNull Class<T> targetClass, @NotNull BundleContext bundleContext) {
        return MockOsgi.activateInjectServices(targetClass, bundleContext, (Map<String, Object>) null);
    }

    /**
     * Simulates OSGi DS dependency injection and activation. Injects direct references and multiple references.
     * If a some references could not be injected no error is thrown.
     * This method instantiates the service instance and also supports constructor injection.
     * @param targetClass Component/service class
     * @param bundleContext Bundle context from which services are fetched to inject.
     * @param properties Service properties (used to resolve dynamic reference properties)
     * @param <T> Target class type
     * @return Component/service instances with injected services
     */
    public static @NotNull <T> T activateInjectServices(
            @NotNull Class<T> targetClass,
            @NotNull BundleContext bundleContext,
            @Nullable Map<String, Object> properties) {
        Map<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(targetClass, getConfigAdmin(bundleContext), properties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        return OsgiServiceUtil.activateInjectServices(targetClass, (MockComponentContext) componentContext);
    }

    /**
     * Simulates OSGi DS dependency injection and activation. Injects direct references and multiple references.
     * If a some references could not be injected no error is thrown.
     * This method instantiates the service instance and also supports constructor injection.
     * @param targetClass Component/service class
     * @param bundleContext Bundle context from which services are fetched to inject.
     * @param properties Service properties (used to resolve dynamic reference properties)
     * @param <T> Target class type
     * @return Component/service instances with injected services
     */
    public static @NotNull <T> T activateInjectServices(
            @NotNull Class<T> targetClass,
            @NotNull BundleContext bundleContext,
            @NotNull Object @NotNull ... properties) {
        return activateInjectServices(targetClass, bundleContext, MapUtil.toMap(properties));
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS Component type
     * @param component a DS component instance
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services
     */
    public static final @NotNull <T> void registerInjectActivateService(
            @NotNull final T component, @NotNull BundleContext bundleContext) {
        registerInjectActivateService(component, bundleContext, (Map<String, Object>) null);
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS Component type
     * @param component a DS component instance
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services
     * @param properties component properties (optional)
     */
    public static final @NotNull <T> void registerInjectActivateService(
            @NotNull final T component,
            @NotNull BundleContext bundleContext,
            @Nullable final Map<String, Object> properties) {
        Map<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(component.getClass(), getConfigAdmin(bundleContext), properties);
        MockOsgi.injectServices(component, bundleContext, mergedProperties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        OsgiServiceUtil.activateDeactivate(component, (MockComponentContext) componentContext, true);
        registerDSComponent(component, bundleContext, mergedProperties);
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS Component type
     * @param component a DS component instance
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services.
     * @param properties component properties (optional)
     */
    public static final @NotNull <T> void registerInjectActivateService(
            @NotNull final T component,
            @NotNull BundleContext bundleContext,
            @NotNull final Object @NotNull ... properties) {
        registerInjectActivateService(component, bundleContext, MapUtil.toMap(properties));
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS component type
     * @param dsComponentClass DS component class
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services
     * @return Registered component instance
     */
    public static final @NotNull <T> T registerInjectActivateService(
            @NotNull final Class<T> dsComponentClass, @NotNull BundleContext bundleContext) {
        return registerInjectActivateService(dsComponentClass, bundleContext, (Map<String, Object>) null);
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS component type
     * @param dsComponentClass DS component class
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services
     * @param properties component properties (optional)
     * @return Registered component instance
     */
    public static final @NotNull <T> T registerInjectActivateService(
            @NotNull Class<T> dsComponentClass,
            @NotNull BundleContext bundleContext,
            @Nullable final Map<String, Object> properties) {
        Map<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(dsComponentClass, getConfigAdmin(bundleContext), properties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        T component = OsgiServiceUtil.activateInjectServices(dsComponentClass, (MockComponentContext) componentContext);
        registerDSComponent(component, bundleContext, mergedProperties);
        return component;
    }

    private static <T> void registerDSComponent(
            @NotNull T component, @NotNull BundleContext bundleContext, Map<String, Object> mergedProperties) {
        OsgiMetadata metadata = Objects.requireNonNull(
                OsgiMetadataUtil.getMetadata(component.getClass()), "No metadata found for " + component.getClass());

        // convert component properties to service properties
        // (http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-service.properties)
        Dictionary<String, Object> serviceProperties = mergedProperties.entrySet().stream()
                .filter(e -> e.getKey() != null && !e.getKey().startsWith("."))
                .collect(new DictionaryCollector<>(Entry::getKey, Entry::getValue));

        // we also register DS Components that aren't services in order for bind/unbind to work - they are registered
        // with no service interfaces
        bundleContext.registerService(
                metadata.getServiceInterfaces().toArray(new String[0]), component, serviceProperties);
    }

    /**
     * Injects dependencies, activates and registers a DS component in the mocked OSGi environment.
     * @param <T> DS component type
     * @param dsComponentClass DS component class
     * @param bundleContext Bundle context from which services are fetched to inject and which is used for registering new services
     * @param properties component properties (optional)
     * @return Registered component instance
     */
    public static final @NotNull <T> T registerInjectActivateService(
            @NotNull Class<T> dsComponentClass,
            @NotNull BundleContext bundleContext,
            @NotNull final Object @NotNull ... properties) {
        return registerInjectActivateService(dsComponentClass, bundleContext, MapUtil.toMap(properties));
    }

    /**
     * Simulates activation of a DS component instance. Invokes the @Activate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @return true if activation method was called. False if no activate method is defined.
     */
    public static boolean activate(@NotNull Object target, @NotNull BundleContext bundleContext) {
        return MockOsgi.activate(target, bundleContext, (Dictionary<String, Object>) null);
    }

    /**
     * Simulates activation of a DS component instance. Invokes the @Activate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if activation method was called. False if no activate method is defined.
     */
    public static boolean activate(
            @NotNull Object target,
            @NotNull BundleContext bundleContext,
            @Nullable Dictionary<String, Object> properties) {
        Dictionary<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(target.getClass(), getConfigAdmin(bundleContext), properties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        return OsgiServiceUtil.activateDeactivate(target, (MockComponentContext) componentContext, true);
    }

    /**
     * Simulates activation of a DS component instance. Invokes the @Activate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if activation method was called. False if no activate method is defined.
     */
    public static boolean activate(
            @NotNull Object target, @NotNull BundleContext bundleContext, @Nullable Map<String, Object> properties) {
        return activate(target, bundleContext, toDictionary(properties));
    }

    /**
     * Simulates activation of a DS component instance. Invokes the @Activate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if activation method was called. False if no activate method is defined.
     */
    public static boolean activate(
            @NotNull Object target, @NotNull BundleContext bundleContext, @NotNull Object @NotNull ... properties) {
        return activate(target, bundleContext, toDictionary(properties));
    }

    /**
     * Simulates deactivation of a DS component instance. Invokes the @Deactivate annotated method.
     * @param target Service instance.
     * @param bundleContext Bundle context.
     * @return true if deactivation method was called. False if no deactivate method is defined.
     */
    public static boolean deactivate(@NotNull Object target, @NotNull BundleContext bundleContext) {
        return MockOsgi.deactivate(target, bundleContext, (Dictionary<String, Object>) null);
    }

    /**
     * Simulates deactivation of a DS component instance. Invokes the @Deactivate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if deactivation method was called. False if no deactivate method is defined.
     */
    public static boolean deactivate(
            @NotNull Object target,
            @NotNull BundleContext bundleContext,
            @Nullable Dictionary<String, Object> properties) {
        Dictionary<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(target.getClass(), getConfigAdmin(bundleContext), properties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        return OsgiServiceUtil.activateDeactivate(target, (MockComponentContext) componentContext, false);
    }

    /**
     * Simulates deactivation of a DS component instance. Invokes the @Deactivate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if deactivation method was called. False if no deactivate method is defined.
     */
    public static boolean deactivate(
            @NotNull Object target, @NotNull BundleContext bundleContext, @Nullable Map<String, Object> properties) {
        return deactivate(target, bundleContext, toDictionary(properties));
    }

    /**
     * Simulates deactivation of a DS component instance. Invokes the @Deactivate annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if deactivation method was called. False if no deactivate method is defined.
     */
    public static boolean deactivate(
            @NotNull Object target, @NotNull BundleContext bundleContext, @NotNull Object @NotNull ... properties) {
        return deactivate(target, bundleContext, toDictionary(properties));
    }

    /**
     * Simulates configuration modification of a DS component instance. Invokes the @Modified annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if modified method was called. False if no modified method is defined.
     */
    public static boolean modified(
            @NotNull Object target,
            @NotNull BundleContext bundleContext,
            @Nullable Dictionary<String, Object> properties) {
        return modified(target, bundleContext, toMap(properties));
    }

    /**
     * Simulates configuration modification of a DS component instance. Invokes the @Modified annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if modified method was called. False if no modified method is defined.
     */
    public static boolean modified(
            @NotNull Object target, @NotNull BundleContext bundleContext, @Nullable Map<String, Object> properties) {
        Map<String, Object> mergedProperties =
                propertiesMergeWithOsgiMetadata(target.getClass(), getConfigAdmin(bundleContext), properties);
        ComponentContext componentContext = newComponentContext(bundleContext, mergedProperties);
        return OsgiServiceUtil.modified(target, (MockComponentContext) componentContext, mergedProperties);
    }

    /**
     * Simulates configuration modification of a DS component instance. Invokes the @Modified annotated method.
     * @param target DS component instance
     * @param bundleContext Bundle context
     * @param properties Properties
     * @return true if modified method was called. False if no modified method is defined.
     */
    public static boolean modified(
            @NotNull Object target, @NotNull BundleContext bundleContext, @NotNull Object @NotNull ... properties) {
        return modified(target, bundleContext, toDictionary(properties));
    }

    /**
     * Set configuration via ConfigurationAdmin service in bundle context for component with given pid.
     * @param bundleContext Bundle context
     * @param pid PID
     * @param properties Configuration properties
     */
    public static void setConfigForPid(
            @NotNull BundleContext bundleContext, @NotNull String pid, @Nullable Map<String, Object> properties) {
        setConfigForPid(bundleContext, pid, toDictionary(properties));
    }

    /**
     * Set configuration via ConfigurationAdmin service in bundle context for component with given pid.
     * @param bundleContext Bundle context
     * @param pid PID
     * @param properties Configuration properties
     */
    public static void setConfigForPid(
            @NotNull BundleContext bundleContext, @NotNull String pid, @NotNull Object @NotNull ... properties) {
        setConfigForPid(bundleContext, pid, toDictionary(properties));
    }

    private static void setConfigForPid(
            @NotNull BundleContext bundleContext,
            @NotNull String pid,
            @Nullable Dictionary<String, Object> properties) {
        ConfigurationAdmin configAdmin = getConfigAdmin(bundleContext);
        if (configAdmin == null) {
            throw new RuntimeException("ConfigurationAdmin service is not registered in bundle context.");
        }
        try {
            Configuration config = configAdmin.getConfiguration(pid);
            config.update(properties);
        } catch (IOException ex) {
            throw new RuntimeException("Unable to update configuration for pid '" + pid + "'.", ex);
        }
    }

    /**
     * Deactivates all bundles registered in the mocked bundle context.
     * @param bundleContext Bundle context
     */
    public static void shutdown(@NotNull BundleContext bundleContext) {
        ((MockBundleContext) bundleContext).shutdown();
    }

    /**
     * Gets configuration admin.
     * @param bundleContext Bundle context
     * @return Configuration admin or null if not registered.
     */
    private static @Nullable ConfigurationAdmin getConfigAdmin(@NotNull BundleContext bundleContext) {
        ServiceReference<?> ref = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
        if (ref != null) {
            return (ConfigurationAdmin) bundleContext.getService(ref);
        }
        return null;
    }
}
