/*
 * 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.auth.core.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.sling.auth.core.AuthConstants;
import org.osgi.framework.AllServiceListener;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.util.converter.Converters;

public class SlingAuthenticatorServiceListener implements AllServiceListener {

    private final PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache;

    private final HashMap<Object, Set<String>> regProps = new HashMap<Object, Set<String>>();

    private final HashMap<Object, List<AuthenticationRequirementHolder>> props = new HashMap<Object, List<AuthenticationRequirementHolder>>();

    static SlingAuthenticatorServiceListener createListener(
        final BundleContext context,
        final PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache) {
        SlingAuthenticatorServiceListener listener = new SlingAuthenticatorServiceListener(authRequiredCache);
        try {
            final String filter = "(" + AuthConstants.AUTH_REQUIREMENTS + "=*)";
            context.addServiceListener(listener, filter);
            ServiceReference<?>[] refs = context.getAllServiceReferences(null,
                filter);
            if (refs != null) {
                for (ServiceReference<?> ref : refs) {
                    listener.addService(ref);
                }
            }
            return listener;
        } catch (InvalidSyntaxException ise) {
        }
        return null;
    }

    private SlingAuthenticatorServiceListener(final PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache) {
        this.authRequiredCache = authRequiredCache;
    }

    @Override
    public void serviceChanged(final ServiceEvent event) {
        synchronized ( props ) {
            // modification of service properties, unregistration of the
            // service or service properties does not contain requirements
            // property any longer (new event with type 8 added in OSGi Core
            // 4.2)
            if ((event.getType() & (ServiceEvent.UNREGISTERING | ServiceEvent.MODIFIED_ENDMATCH)) != 0) {
                removeService(event.getServiceReference());
            }

            if ((event.getType() & ServiceEvent.MODIFIED ) != 0) {
                modifiedService(event.getServiceReference());
            }

            // add requirements for newly registered services and for
            // updated services
            if ((event.getType() & ServiceEvent.REGISTERED ) != 0) {
                addService(event.getServiceReference());
            }
        }
    }

    /**
     * Register all known services.
     */
    void registerAllServices() {
        for(final List<AuthenticationRequirementHolder> authReqs : props.values()) {
            registerService(authReqs);
        }
    }

    /**
     * Register all authentication requirement holders.
     * @param authReqs The auth requirement holders
     */
    private void registerService(final List<AuthenticationRequirementHolder> authReqs) {
        for (AuthenticationRequirementHolder authReq : authReqs) {
            authRequiredCache.addHolder(authReq);
        }
    }

    private Set<String> buildPathsSet(final String[] authReqPaths) {
        final Set<String> paths = new HashSet<>();
        for(final String authReq : authReqPaths) {
            if (authReq != null && authReq.length() > 0) {
                paths.add(authReq);
            }
        }
        return paths;
    }

    /**
     * Process a new service with auth requirements
     * @param ref The service reference
     */
    private void addService(final ServiceReference<?> ref) {
        final String[] authReqPaths = Converters.standardConverter().convert(ref.getProperty(AuthConstants.AUTH_REQUIREMENTS)).to(String[].class);
        if ( authReqPaths != null ) {
            final Set<String> paths = buildPathsSet(authReqPaths);

            if ( !paths.isEmpty() ) {
                final List<AuthenticationRequirementHolder> authReqList = new ArrayList<AuthenticationRequirementHolder>();
                for (final String authReq : paths) {
                    authReqList.add(AuthenticationRequirementHolder.fromConfig(
                        authReq, ref));
                }

                // keep original set for modified
                regProps.put(ref.getProperty(Constants.SERVICE_ID), paths);
                registerService(authReqList);
                props.put(ref.getProperty(Constants.SERVICE_ID), authReqList);
            }
        }
    }

    /**
     * Process a modified service with auth requirements
     * @param ref The service reference
     */
    private void modifiedService(final ServiceReference<?> ref) {
        final String[] authReqPaths = Converters.standardConverter().convert(ref.getProperty(AuthConstants.AUTH_REQUIREMENTS)).to(String[].class);
        if ( authReqPaths != null ) {
            final Set<String> oldPaths = regProps.get(ref.getProperty(Constants.SERVICE_ID));
            if ( oldPaths == null ) {
                addService(ref);
            } else {
                final Set<String> paths = buildPathsSet(authReqPaths);
                if ( paths.isEmpty() ) {
                    removeService(ref);
                } else {
                    final List<AuthenticationRequirementHolder> authReqs = props.get(ref.getProperty(Constants.SERVICE_ID));
                    // compare sets
                    for(final String oldPath : oldPaths) {
                        if ( !paths.contains(oldPath) ) {
                            // remove
                            final AuthenticationRequirementHolder holder = AuthenticationRequirementHolder.fromConfig(oldPath, ref);
                            authReqs.remove(holder);
                            authRequiredCache.removeHolder(holder);
                        }
                    }
                    for(final String path : paths) {
                        if ( !oldPaths.contains(path) ) {
                            // add
                            final AuthenticationRequirementHolder holder = AuthenticationRequirementHolder.fromConfig(path, ref);
                            authReqs.add(holder);
                            authRequiredCache.addHolder(holder);
                        }
                    }
                    regProps.put(ref.getProperty(Constants.SERVICE_ID), paths);
                }
            }
        } else {
            removeService(ref);
        }
    }

    /**
     * Process a removed service with auth requirements
     * @param ref The service reference
     */
    private void removeService(final ServiceReference<?> ref) {
        final List<AuthenticationRequirementHolder> authReqs = props.remove(ref.getProperty(Constants.SERVICE_ID));
        if (authReqs != null) {
            for (final AuthenticationRequirementHolder authReq : authReqs) {
                authRequiredCache.removeHolder(authReq);
            }
        }
        regProps.remove(ref.getProperty(Constants.SERVICE_ID));
    }
}
