/*
 * 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.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 ObservationReporter reporter, final 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[excludePaths.size()]));
            }

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

            // types
            filter.setEventTypes(this.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 ObservationReporter getReporter() {
        return this.reporter;
    }
}
