/*
 * 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.felix.cm.impl.helper;


import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.felix.cm.impl.ConfigurationManager;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;


public class ManagedServiceTracker extends BaseTracker<ManagedService>
{

    private static final Dictionary<String, ?> INITIAL_MARKER = new Hashtable<String, Object>( 0 );


    public ManagedServiceTracker( ConfigurationManager cm )
    {
        super( cm, false );
    }


    @Override
    protected ConfigurationMap<?> createConfigurationMap( String[] pids )
    {
        return new ManagedServiceConfigurationMap( pids );
    }


    @Override
    public String getServicePid( ServiceReference<ManagedService> service, TargetedPID pid )
    {
        final ConfigurationMap configs = this.getService( service );
        if ( configs != null )
        {
            return configs.getKeyPid( pid );
        }

        // this service is not handled...
        return null;
    }


    /**
     * Provides the given configuration to the managed service.
     * <p>
     * Depending on targeted PIDs this configuration may not actually be
     * provided if the service already has more strictly binding
     * configuration from a targeted configuration bound.
     * <p>
     * If the revision is a negative value, the provided configuration
     * is assigned to the ManagedService in any case without further
     * checks. This allows a replacement configuration for a deleted
     * or invisible configuration to be assigned without first removing
     * the deleted or invisible configuration.
     */
    @Override
    public void provideConfiguration( ServiceReference<ManagedService> service, TargetedPID configPid,
        TargetedPID factoryPid, Dictionary<String, ?> properties, long revision, ConfigurationMap<?> configs )
    {
        Dictionary<String, ?> supplied = ( properties == null ) ? INITIAL_MARKER : properties;
        updateService( service, configPid, supplied, revision, configs );
    }


    @Override
    public void removeConfiguration( ServiceReference<ManagedService> service, TargetedPID configPid,
        TargetedPID factoryPid )
    {
        updateService( service, configPid, null, -1, null );
    }


    private void updateService( ServiceReference<ManagedService> service, final TargetedPID configPid,
        Dictionary<String, ?> properties, long revision, ConfigurationMap<?> configs)
    {
        // Get the ManagedService and terminate here if already
        // unregistered from the framework concurrently
        final ManagedService srv = this.getRealService( service );
        if (srv == null) {
            return;
        }

        // Get the Configuration-to-PID map from the parameter or from
        // the service tracker. If not available, the service tracker
        // already unregistered this service concurrently
        if ( configs == null )
        {
            configs = this.getService( service );
            if ( configs == null )
            {
                return;
            }
        }

        // Both the ManagedService to update and the Configuration-to-PID
        // are available, so the service can be updated with the
        // configuration (which may be null)

        boolean doUpdate = false;
        if ( properties == null )
        {
            doUpdate = configs.removeConfiguration( configPid, null );
        }
        else if ( properties == INITIAL_MARKER )
        {
            // initial call to ManagedService may supply null properties
            properties = null;
            revision = -1;
            doUpdate = true;
        }
        else if ( revision < 0 || configs.shallTake( configPid, null, revision ) )
        {
            // run the plugins and cause the update
            properties = getProperties( properties, service, configPid.toString(), null );
            doUpdate = true;
            revision = Math.abs( revision );
        }
        else
        {
            // new configuration is not a better match, don't update
            doUpdate = false;
        }

        if ( doUpdate )
        {
            try
            {
                updated( service, srv, properties );
                configs.record( configPid, null, revision );
            }
            catch ( Throwable t )
            {
                this.handleCallBackError( t, service, configPid );
            }
            finally
            {
                this.ungetRealService( service );
            }
        }
    }


    private void updated( final ServiceReference<ManagedService> reference, final ManagedService service, final Dictionary properties) throws ConfigurationException
    {
        if ( System.getSecurityManager() != null )
        {
            try
            {
                AccessController.doPrivileged( new PrivilegedExceptionAction()
                {
                    public Object run() throws ConfigurationException
                    {
                        service.updated( properties );
                        return null;
                    }
                }, getAccessControlContext( reference.getBundle() ) );
            }
            catch ( PrivilegedActionException e )
            {
                throw ( ConfigurationException ) e.getException();
            }
        }
        else
        {
            service.updated( properties );
        }
    }
}