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

import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.sql.DataSource;

import org.apache.aries.jpa.container.parser.impl.PersistenceUnit;
import org.apache.aries.jpa.container.weaving.impl.DummyDataSource;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.jpa.EntityManagerFactoryBuilder;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Tracks matching persistence providers for a persistence unit.
 * If a provider is found:
 * - an EntityManagerFactoryBuilder is installed
 * - A DataSourceTracker is installed if the JtaDataSource refers to an OSGi service 
 */
public class PersistenceProviderTracker extends ServiceTracker<PersistenceProvider, StoredPerProvider> {
    private static final String JAVAX_PERSISTENCE_PROVIDER = "javax.persistence.provider";

    private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceProviderTracker.class);

    private PersistenceUnit punit;

    public PersistenceProviderTracker(BundleContext context, PersistenceUnit punit) {
        super(context, createFilter(context, punit), null);
        this.punit = punit;
    }

    private static Filter createFilter(BundleContext context, PersistenceUnit punit) {
        String filter = null;
        if (punit.getPersistenceProviderClassName() != null) {
            filter = String.format("(&(objectClass=%s)(%s=%s))",
                                   PersistenceProvider.class.getName(),
                                   JAVAX_PERSISTENCE_PROVIDER,
                                   punit.getPersistenceProviderClassName());
        } else {
            filter = String.format("(objectClass=%s)", PersistenceProvider.class.getName());
        }

        try {
            return context.createFilter(filter);
        } catch (InvalidSyntaxException e) {
            throw new IllegalArgumentException(e);
        }
    }

    @Override
    public StoredPerProvider addingService(ServiceReference<PersistenceProvider> reference) {
        String providerName = (String)reference.getProperty(JAVAX_PERSISTENCE_PROVIDER);
        // FIXME should be set when creating the EMF was successful
        if (punit.getPersistenceProviderClassName() == null) {
            punit.setProviderClassName(providerName);
        }
        StoredPerProvider stored = new StoredPerProvider();
        LOGGER.info("Found provider for " + punit.getPersistenceUnitName() + " " + punit.getPersistenceProviderClassName());
        PersistenceProvider provider = context.getService(reference);

        createAndCloseDummyEMF(provider);

        stored.dsTracker = createDataSourceTracker(stored, provider, providerName);
        EntityManagerFactoryBuilder emfBuilder = new AriesEntityManagerFactoryBuilder(provider, punit);
        Dictionary<String, ?> props = ManagedEMF.createProperties(punit, punit.getBundle());
        stored.reg = context.registerService(EntityManagerFactoryBuilder.class, emfBuilder , props);
        return stored;
    }

    /**
     * Create and close a dummy EMF to give the PersistenceProvider a chance to call
     * punit.addTransformer(). This has to occur as early as possible as weaving needs
     * to be done before the first entity class is loaded. So we can not wait till the
     * real DataSource is found.
     */
    private void createAndCloseDummyEMF(PersistenceProvider provider) {
        DataSource dummyDataSource = new DummyDataSource();
        punit.setJtaDataSource(dummyDataSource);
        punit.setNonJtaDataSource(dummyDataSource);
        try {
            EntityManagerFactory emf = provider.createContainerEntityManagerFactory(punit, null);
            emf.close();
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
        }
        punit.setJtaDataSource(null);
        punit.setNonJtaDataSource(null);
    }

    private ServiceTracker<?, ?> createDataSourceTracker(StoredPerProvider stored, PersistenceProvider provider, String providerName) {
        if (usesDataSource()) {
            if (!usesDataSourceService()) {
                LOGGER.warn("Persistence unit " + punit.getPersistenceUnitName() + " refers to a non OSGi service DataSource");
                return null;
            }
            DataSourceTracker dsTracker = new DataSourceTracker(context, provider, punit);
            dsTracker.open();
            return dsTracker;
        } else if (usesDSF()) {
            DSFTracker dsfTracker = new DSFTracker(context, provider, punit);
            dsfTracker.open();
            return dsfTracker;
        } else {
            LOGGER.debug("Persistence unit " + punit.getPersistenceUnitName() + " does not refer a DataSource. "
                         +"It can only be used with EntityManagerFactoryBuilder.");
            return null;
        }
    }

    private boolean usesDataSource() {
        return punit.getJtaDataSourceName() != null || punit.getNonJtaDataSourceName() != null;
    }

    private boolean usesDSF() {
        return DSFTracker.getDriverName(punit) != null;
    }

    private boolean usesDataSourceService() {
        return punit.getJtaDataSourceName() != null && punit.getJtaDataSourceName().startsWith(DataSourceTracker.DS_PREFIX)
            || punit.getNonJtaDataSourceName() != null && punit.getNonJtaDataSourceName().startsWith(DataSourceTracker.DS_PREFIX);
    }

    @Override
    public void removedService(ServiceReference<PersistenceProvider> reference, StoredPerProvider stored) {
        LOGGER.info("Lost provider for " + punit.getPersistenceUnitName() + " " + punit.getPersistenceProviderClassName());
        if (stored.dsTracker != null) {
            stored.dsTracker.close();
        }
        stored.reg.unregister();
        super.removedService(reference, stored);
    }
}
