/*
 * 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 java.io.Closeable;
import java.util.Set;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;

import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;
import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;
import org.apache.jackrabbit.oak.jcr.observation.filter.FilterFactory;
import org.apache.jackrabbit.oak.jcr.observation.filter.OakEventFilter;
import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.spi.resource.provider.ObservationReporter;
import org.apache.sling.spi.resource.provider.ObserverConfiguration;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This is the base configuration for a JCR listener, shared
 * by all registered {@link JcrResourceListener}s.
 */
public class JcrListenerBaseConfig implements Closeable {

    private final Logger logger = LoggerFactory.getLogger(JcrListenerBaseConfig.class);

    private final Session session;

    private final ObservationReporter reporter;

    @SuppressWarnings("deprecation")
    public JcrListenerBaseConfig(final @NotNull ObservationReporter reporter, final @NotNull SlingRepository repository) throws RepositoryException {
        this.reporter = reporter;
        // The session should have read access on the whole repository
        this.session = repository.loginService("observation", repository.getDefaultWorkspace());
    }

    /**
     * Dispose this config
     * Close session.
     */
    @Override
    public void close() {
        this.session.logout();
    }

    /**
     * Register a JCR event listener
     * @param listener The listener
     * @param config The configuration
     * @throws RepositoryException If registration fails.
     */
    public void register(final EventListener listener, final ObserverConfiguration config) throws RepositoryException {
        final ObservationManager mgr = this.session.getWorkspace().getObservationManager();
        if (mgr instanceof JackrabbitObservationManager) {
            final OakEventFilter filter = FilterFactory.wrap(new JackrabbitEventFilter());
            // paths
            final Set<String> paths = config.getPaths().toStringSet();
            int globCount = 0;
            int pathCount = 0;
            for (final String p : paths) {
                if (p.startsWith(Path.GLOB_PREFIX)) {
                    globCount++;
                } else {
                    pathCount++;
                }
            }
            final String[] pathArray = pathCount > 0 ? new String[pathCount] : null;
            final String[] globArray = globCount > 0 ? new String[globCount] : null;
            pathCount = 0;
            globCount = 0;

            // create arrays and remove global prefix
            for (final String p : paths) {
                if (p.startsWith(Path.GLOB_PREFIX)) {
                    globArray[globCount] = p.substring(Path.GLOB_PREFIX.length());
                    globCount++;
                } else {
                    pathArray[pathCount] = p;
                    pathCount++;
                }
            }
            if (globArray != null) {
                filter.withIncludeGlobPaths(globArray);
            }
            if (pathArray != null) {
                filter.setAdditionalPaths(pathArray);
            }
            filter.setIsDeep(true);

            // exclude paths
            final Set<String> excludePaths = config.getExcludedPaths().toStringSet();
            if (!excludePaths.isEmpty()) {
                filter.setExcludedPaths(excludePaths.toArray(new String[0]));
            }

            // external
            filter.setNoExternal(!config.includeExternal());

            // types
            filter.setEventTypes(getTypes(config));

            // nt:file handling
            filter.withNodeTypeAggregate(new String[]{"nt:file"}, new String[]{"", "jcr:content"});

            // ancestors remove
            filter.withIncludeAncestorsRemove();

            ((JackrabbitObservationManager) mgr).addEventListener(listener, filter);
        } else {
            throw new RepositoryException("Observation manager is not a JackrabbitObservationManager");
        }

    }

    /**
     * Get the event types based on the configuration
     * @param c The configuration
     * @return The event type mask
     */
    private static int getTypes(final ObserverConfiguration c) {
        int result = 0;
        for (ChangeType t : c.getChangeTypes()) {
            switch (t) {
                case ADDED:
                    result = result | Event.NODE_ADDED;
                    break;
                case REMOVED:
                    result = result | Event.NODE_REMOVED;
                    break;
                case CHANGED:
                    result = result | Event.PROPERTY_ADDED;
                    result = result | Event.PROPERTY_CHANGED;
                    result = result | Event.PROPERTY_REMOVED;
                    break;
                default:
                    break;
            }
        }
        return result;
    }

    /**
     * Unregister the listener.
     * @param listener The listener
     */
    public void unregister(final EventListener listener) {
        try {
            this.session.getWorkspace().getObservationManager().removeEventListener(listener);
        } catch (final RepositoryException e) {
            logger.warn("Unable to remove session listener: " + this, e);
        }
    }

    /**
     * The observation reporter
     * @return The observation reporter.
     */
    public @NotNull ObservationReporter getReporter() {
        return this.reporter;
    }
}
