/*
 * 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.event.dea.impl;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

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.resource.ValueMap;
import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.apache.sling.event.dea.DEAConstants;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This event handler distributes events from other application nodes in
 * the cluster on the current instance.
 * <p>
 * It's listening for resource added events in the resource tree storing the
 * distributed events. If a new resource is added, the resource is read,
 * converted to an event and then send using the local event admin.
 * <p>
 */
public class DistributedEventSender
    implements ResourceChangeListener, ExternalResourceChangeListener {

    /** Default logger. */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /** Is the background task still running? */
    private volatile boolean running;

    /** A local queue for serializing the event processing. */
    private final BlockingQueue<String> queue = new LinkedBlockingQueue<String>();

    private final ResourceResolverFactory resourceResolverFactory;

    private final EventAdmin eventAdmin;

    private final String ownRootPathWithSlash;

    private volatile ServiceRegistration<ResourceChangeListener> serviceRegistration;

    public DistributedEventSender(final BundleContext bundleContext,
            final String rootPath,
            final String ownRootPath,
            final ResourceResolverFactory rrFactory,
            final EventAdmin eventAdmin) {
        this.eventAdmin = eventAdmin;
        this.resourceResolverFactory = rrFactory;
        this.ownRootPathWithSlash = ownRootPath + "/";

        this.running = true;
        final Thread backgroundThread = new Thread(new Runnable() {
            @Override
            public void run() {
                // create service registration properties
                final Dictionary<String, Object> props = new Hashtable<String, Object>();
                props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");

                // listen for all resource added OSGi events in the DEA area
                props.put(ResourceChangeListener.CHANGES, ResourceChange.ChangeType.ADDED.name());
                props.put(ResourceChangeListener.PATHS, rootPath);

                final ServiceRegistration<ResourceChangeListener> reg =
                        bundleContext.registerService(ResourceChangeListener.class,
                                       DistributedEventSender.this, props);

                DistributedEventSender.this.serviceRegistration = reg;

                try {
                    runInBackground();
                } catch (Throwable t) { //NOSONAR
                    logger.error("Background thread stopped with exception: " + t.getMessage(), t);
                    running = false;
                }
            }
        });
        backgroundThread.start();
    }

    /**
     * Deactivate this component.
     */
    public void stop() {
        if ( this.serviceRegistration != null ) {
            this.serviceRegistration.unregister();
            this.serviceRegistration = null;
        }
        // stop background threads by putting empty objects into the queue
        this.running = false;
        try {
            this.queue.put("");
        } catch (final InterruptedException e) {
            this.ignoreException(e);
            Thread.currentThread().interrupt();
        }
    }

    /**
     * Read an event from the resource
     * @return The event object or <code>null</code>
     */
    private Event readEvent(final Resource eventResource) {
        try {
            final ValueMap vm = ResourceHelper.getValueMap(eventResource);
            final String topic = vm.get(EventConstants.EVENT_TOPIC, String.class);
            if ( topic == null ) {
                // no topic should never happen as we check the resource type before
                logger.error("Unable to read distributed event from " + eventResource.getPath() + " : no topic property available.");
            } else {
                final Map<String, Object> properties = ResourceHelper.cloneValueMap(vm);
                // only send event if there are no read errors, otherwise discard it
                @SuppressWarnings("unchecked")
                final List<Exception> readErrorList = (List<Exception>) properties.remove(ResourceHelper.PROPERTY_MARKER_READ_ERROR_LIST);
                if ( readErrorList == null ) {
                    properties.remove(EventConstants.EVENT_TOPIC);
                    properties.remove(DEAConstants.PROPERTY_DISTRIBUTE);
                    final Object oldRT = properties.remove("event.dea." + ResourceResolver.PROPERTY_RESOURCE_TYPE);
                    if ( oldRT != null ) {
                        properties.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, oldRT);
                    } else {
                        properties.remove(ResourceResolver.PROPERTY_RESOURCE_TYPE);
                    }
                    try {
                        final Event event = new Event(topic, properties);
                        return event;
                    } catch (final IllegalArgumentException iae) {
                        // this exception occurs if the topic is not correct (it should never happen,
                        // but you never know)
                        logger.error("Unable to read event: " + iae.getMessage(), iae);
                    }
                } else {
                    for(final Exception e : readErrorList) {
                        logger.warn("Unable to read distributed event from " + eventResource.getPath(), e);
                    }
                }
            }
        } catch (final InstantiationException ie) {
            // something happened with the resource in the meantime
            this.ignoreException(ie);
        }
        return null;
    }

    /**
     * Background thread
     */
    private void runInBackground() {
        while ( this.running ) {
            // so let's wait/get the next event from the queue
            String path = null;
            try {
                path = this.queue.take();
            } catch (final InterruptedException e) {
                this.ignoreException(e);
                Thread.currentThread().interrupt();
                this.running = false;
            }
            if ( path != null && path.length() > 0 && this.running ) {
                ResourceResolver resolver = null;
                try {
                    resolver = this.resourceResolverFactory.getServiceResourceResolver(null);
                    final Resource eventResource = resolver.getResource(path);
                    if (eventResource == null) {
                        this.logger.warn("runInBackground : resource not found at "+path);
                    } else if ( DistributedEventAdminImpl.RESOURCE_TYPE_EVENT.equals(eventResource.getResourceType())) {
                        final Event e = this.readEvent(eventResource);
                        if ( e != null ) {
                            // we check event admin as processing is async
                            final EventAdmin localEA = this.eventAdmin;
                            if ( localEA != null ) {
                                localEA.postEvent(e);
                            } else {
                                this.logger.error("Unable to post event as no event admin is available.");
                            }
                        }
                    }
                } catch (final LoginException ex) {
                    this.logger.error("Exception during creation of resource resolver.", ex);
                } finally {
                    if ( resolver != null ) {
                        resolver.close();
                    }
                }
            }
        }
    }

    /**
     * @see org.apache.sling.api.resource.observation.ResourceChangeListener#onChange(java.util.List)
     */
    @Override
    public void onChange(final List<ResourceChange> changes) {
        for(final ResourceChange c : changes) {
            if ( !c.getPath().startsWith(this.ownRootPathWithSlash) ) {
                try {
                    this.queue.put(c.getPath());
                } catch (final InterruptedException ex) {
                    this.ignoreException(ex);
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    /**
     * Helper method which just logs the exception in debug mode.
     * @param e
     */
    private void ignoreException(final Exception e) {
        if ( this.logger.isDebugEnabled() ) {
            this.logger.debug("Ignored exception " + e.getMessage(), e);
        }
    }
}
