/*
 * 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.jcr.resource.internal;

import static javax.jcr.observation.Event.NODE_ADDED;
import static javax.jcr.observation.Event.NODE_REMOVED;
import static javax.jcr.observation.Event.PROPERTY_ADDED;
import static javax.jcr.observation.Event.PROPERTY_CHANGED;
import static javax.jcr.observation.Event.PROPERTY_REMOVED;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.RepositoryException;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;

import org.apache.jackrabbit.api.observation.JackrabbitEvent;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
import org.apache.sling.spi.resource.provider.ObservationReporter;
import org.apache.sling.spi.resource.provider.ObserverConfiguration;
import org.jetbrains.annotations.NotNull;

/**
 * The <code>JcrResourceListener</code> listens for JCR observation
 * events and creates resource change events which are sent through
 * the {@link ObservationReporter}.
 */
public class JcrResourceListener implements EventListener, Closeable {

    private volatile ObserverConfiguration config;

    private final JcrListenerBaseConfig baseConfig;

    public JcrResourceListener(@NotNull final JcrListenerBaseConfig listenerConfig, 
                               @NotNull final ObserverConfiguration config) throws RepositoryException {
        this.baseConfig = listenerConfig;
        this.config = config;
        this.baseConfig.register(this, config);
    }

    /**
     * Update the observation configuration.
     *
     * @param cfg The updated config
     */
    public void update(final ObserverConfiguration cfg) {
        this.config = cfg;
    }

    /**
     * Get the observation configuration
     * @return The observation configuration
     */
    public ObserverConfiguration getConfig() {
        return this.config;
    }

    /**
     * Dispose this listener.
     */
    @Override
    public void close() {
        // unregister from observations
        this.baseConfig.unregister(this);
    }

    /**
     * @see javax.jcr.observation.EventListener#onEvent(javax.jcr.observation.EventIterator)
     */
    @Override
    public void onEvent(final EventIterator events) {
        final Map<String, ResourceChange> addedEvents = new HashMap<>();
        final Map<String, ResourceChange> changedEvents = new HashMap<>();
        final Map<String, ResourceChange> removedEvents = new HashMap<>();

        while (events.hasNext()) {
            final Event event = events.nextEvent();

            final String identifier;
            final String path;
            try {
                identifier = event.getIdentifier();
                path = event.getPath();
            } catch (final RepositoryException e) {
                // event.getPath or event.getIdentifier threw an exception
                // there is nothing we can do about it anyway
                continue;
            }

            final String eventPath = (identifier != null && identifier.startsWith("/") ? identifier : path);
            final int type = event.getType();

            if (type == PROPERTY_ADDED && path.endsWith("/jcr:primaryType")) {
                final int lastSlash = path.lastIndexOf('/');
                final String rsrcPath = path.substring(0, lastSlash);

                // add is stronger than update
                changedEvents.remove(rsrcPath);
                addedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.ADDED));
            } else if (type == PROPERTY_ADDED
                    || type == PROPERTY_REMOVED
                    || type == PROPERTY_CHANGED) {
                final String rsrcPath;
                if (identifier == null || !identifier.startsWith("/")) {
                    final int lastSlash = eventPath.lastIndexOf('/');
                    rsrcPath = eventPath.substring(0, lastSlash);
                } else {
                    rsrcPath = eventPath;
                }
                if (!addedEvents.containsKey(rsrcPath)
                        && !removedEvents.containsKey(rsrcPath)
                        && !changedEvents.containsKey(rsrcPath)) {

                    changedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.CHANGED));
                }
            } else if (type == NODE_ADDED) {
                // add is stronger than update
                changedEvents.remove(eventPath);
                addedEvents.put(eventPath, createResourceChange(event, eventPath, ChangeType.ADDED));
            } else if (type == NODE_REMOVED) {
                // remove is stronger than add and change
                addedEvents.remove(eventPath);
                changedEvents.remove(eventPath);
                removedEvents.put(eventPath, createResourceChange(event, eventPath, ChangeType.REMOVED));
            }
        }

        final List<ResourceChange> changes = new ArrayList<>();
        changes.addAll(addedEvents.values());
        changes.addAll(removedEvents.values());
        changes.addAll(changedEvents.values());
        this.baseConfig.getReporter().reportChanges(this.config, changes, false);

    }

    private static @NotNull ResourceChange createResourceChange(@NotNull final Event event,
                                                                @NotNull final String path,
                                                                @NotNull final ChangeType changeType) {
        final boolean isExternal = isExternal(event);
        final String userId;
        if (!isExternal) {
            userId = event.getUserID();
        } else {
            userId = null;
        }
        return new JcrResourceChange(changeType, path, isExternal, userId);
    }

    private static boolean isExternal(@NotNull final Event event) {
        if (event instanceof JackrabbitEvent) {
            final JackrabbitEvent jEvent = (JackrabbitEvent) event;
            return jEvent.isExternal();
        }
        return false;
    }

    @Override
    public String toString() {
        return "JcrResourceListener [" + config + "]";
    }
}
