/*
 * 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 WARRANTIESOR 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.aries.jpa.container.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.aries.jpa.container.parser.impl.PersistenceUnit;
import org.apache.aries.jpa.container.parser.impl.PersistenceUnitParser;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Looks for bundles containing a persistence.xml. For each persistence unit
 * found a PersistenceProviderTracker is installed that tracks matching providers.
 */
@SuppressWarnings("deprecation")
public class PersistenceBundleTracker implements BundleTrackerCustomizer<Bundle> {
    private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceBundleTracker.class);
    Map<Bundle, Collection<PersistenceProviderTracker>> trackers;
    private BundleContext context;

    public PersistenceBundleTracker(BundleContext context) {
        this.context = context;
        trackers = new HashMap<Bundle, Collection<PersistenceProviderTracker>>();
    }

    public Bundle addingBundle(Bundle bundle, BundleEvent event) {
        if (getTrackers(bundle).size() == 0) {
            findPersistenceUnits(bundle);
        }
        return bundle;
    }

    public void removedBundle(Bundle bundle, BundleEvent event, Bundle object) {
        Collection<PersistenceProviderTracker> providerTrackers = trackers.get(bundle);
        if (providerTrackers != null) {
            if (providerTrackers.size() > 0)  {
                LOGGER.info("removing persistence units for " + bundle.getSymbolicName() + " " + getType(event));
            }
            for (PersistenceProviderTracker providerTracker : providerTrackers) {
                providerTracker.close();
            }
            providerTrackers.clear();
            trackers.remove(bundle);
        }
    }

    private void findPersistenceUnits(Bundle bundle) {
        ServiceReference<PackageAdmin> ref = context.getServiceReference(PackageAdmin.class);
        PackageAdmin packageAdmin = context.getService(ref);
        for (PersistenceUnit punit : PersistenceUnitParser.getPersistenceUnits(bundle)) {
            punit.addAnnotated(packageAdmin);
            trackProvider(bundle, punit);
        }
        context.ungetService(ref);
    }

    private void trackProvider(Bundle bundle, 
                               PersistenceUnit punit) {
        LOGGER.info(String.format("Found persistence unit %s in bundle %s with provider %s.",
                                  punit.getPersistenceUnitName(), bundle.getSymbolicName(),
                                  punit.getPersistenceProviderClassName()));
        PersistenceProviderTracker tracker = new PersistenceProviderTracker(context, punit);
        tracker.open();
        getTrackers(bundle).add(tracker);
    }

    @Override
    public void modifiedBundle(Bundle bundle, BundleEvent event, Bundle object) {
    }

    private static String getType(BundleEvent event) {
        if (event == null) {
            return "null";
        }
        int type = event.getType();
        switch (type) {
        case BundleEvent.INSTALLED:
            return "INSTALLED";
        case BundleEvent.LAZY_ACTIVATION:
            return "LAZY_ACTIVATION";
        case BundleEvent.RESOLVED:
            return "RESOLVED";
        case BundleEvent.STARTED:
            return "STARTED";
        case BundleEvent.STARTING:
            return "Starting";
        case BundleEvent.STOPPED:
            return "STOPPED";
        case BundleEvent.UNINSTALLED:
        case 256: // Not sure why but this event is sent when a bundle is uninstalled
            return "UNINSTALLED";
        case BundleEvent.UNRESOLVED:
            return "UNRESOLVED";
        case BundleEvent.UPDATED:
            return "UPDATED";
        default:
            return "unknown event type: " + type;
        }
    }
    
    private Collection<PersistenceProviderTracker> getTrackers(Bundle bundle) {
        Collection<PersistenceProviderTracker> providerTrackers = trackers.get(bundle);
        if (providerTrackers == null) {
            providerTrackers = new ArrayList<>();
            trackers.put(bundle, providerTrackers);
        }
        return providerTrackers;
    }

}
