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

import java.util.HashMap;
import java.util.Map;

import org.apache.felix.utils.log.Logger;
import org.osgi.framework.AllServiceListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.SynchronousBundleListener;
import org.apache.felix.bundlerepository.*;

public class LocalRepositoryImpl implements Repository, SynchronousBundleListener, AllServiceListener
{
    private final BundleContext m_context;
    private final Logger m_logger;
    private long m_snapshotTimeStamp = 0;
    private Map<Long, Resource> m_localResourceList = new HashMap<Long, Resource>();

    public LocalRepositoryImpl(BundleContext context, Logger logger)
    {
        m_context = context;
        m_logger = logger;
        initialize();
    }

    public void bundleChanged(BundleEvent event)
    {
        if (event.getType() == BundleEvent.INSTALLED || event.getType() == BundleEvent.UPDATED)
        {
            synchronized (this)
            {
                addBundle(event.getBundle());
                m_snapshotTimeStamp = System.currentTimeMillis();
            }
        }
        else if (event.getType() == BundleEvent.UNINSTALLED)
        {
            synchronized (this)
            {
                removeBundle(event.getBundle());
                m_snapshotTimeStamp = System.currentTimeMillis();
            }
        }
    }

    public void serviceChanged(ServiceEvent event)
    {
        Bundle bundle = event.getServiceReference().getBundle();
        if ((bundle != null)
            && (bundle.getState() == Bundle.ACTIVE && event.getType() != ServiceEvent.MODIFIED))
        {
            synchronized (this)
            {
                removeBundle(bundle);
                addBundle(bundle);
                m_snapshotTimeStamp = System.currentTimeMillis();
            }
        }
    }

    private void addBundle(Bundle bundle)
    {
        /*
         * Concurrency note: This method MUST be called in a context which
         * is synchronized on this instance to prevent data structure
         * corruption.
         */

        // Ignore system bundle
        if (bundle.getBundleId() == 0)
        {
            return;
        }
        m_localResourceList.put(bundle.getBundleId(), new LazyLocalResourceImpl(bundle, m_logger));
    }

    private void removeBundle(Bundle bundle)
    {
        /*
         * Concurrency note: This method MUST be called in a context which
         * is synchronized on this instance to prevent data structure
         * corruption.
         */

        m_localResourceList.remove(bundle.getBundleId());
    }

    public void dispose()
    {
        m_context.removeBundleListener(this);
        m_context.removeServiceListener(this);
    }

    public String getURI()
    {
        return LOCAL;
    }

    public String getName()
    {
        return "Locally Installed Repository";
    }

    public synchronized long getLastModified()
    {
        return m_snapshotTimeStamp;
    }

    public synchronized Resource[] getResources()
    {
        return m_localResourceList.values().toArray(new Resource[m_localResourceList.size()]);
    }

    private void initialize()
    {
        // register for bundle and service events now
        m_context.addBundleListener(this);
        m_context.addServiceListener(this);

        // Generate the resource list from the set of installed bundles.
        // Lock so we can ensure that no bundle events arrive before we
        // are done getting our state snapshot.
        Bundle[] bundles;
        synchronized (this)
        {
            // Create a local resource object for each bundle, which will
            // convert the bundle headers to the appropriate resource metadata.
            bundles = m_context.getBundles();
            for (int i = 0; (bundles != null) && (i < bundles.length); i++)
            {
                addBundle(bundles[i]);
            }

            m_snapshotTimeStamp = System.currentTimeMillis();
        }
    }
}