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

import static org.osgi.service.jpa.EntityManagerFactoryBuilder.JPA_UNIT_NAME;

import java.lang.reflect.Proxy;
import java.util.Dictionary;
import java.util.Hashtable;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceUnitTransactionType;

import org.apache.aries.jpa.supplier.EmSupplier;
import org.apache.aries.jpa.support.impl.EMSupplierImpl;
import org.apache.aries.jpa.support.impl.ResourceLocalJpaTemplate;
import org.apache.aries.jpa.template.JpaTemplate;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.coordinator.Coordinator;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Tracks EntityManagerFactory services and publishes a Supplier&lt;EntityManager&gt; for each.
 * IF the persistence unit uses JTA a TMTracker is created. If it uses RESOURCE_LOCAL as 
 * ResourceLocalJpaTemplate is created.
 */
@SuppressWarnings("rawtypes")
public class EMFTracker extends ServiceTracker {
    private static final Logger LOG = LoggerFactory.getLogger(EMFTracker.class);

    private Coordinator coordinator;

    @SuppressWarnings("unchecked")
    public EMFTracker(BundleContext context, Coordinator coordinator) {
        super(context, EntityManagerFactory.class, null);
        this.coordinator = coordinator;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Object addingService(ServiceReference reference) {
        String unitName = (String)reference.getProperty(JPA_UNIT_NAME);
        if (unitName == null) {
            return null;
        }
        BundleContext puContext = reference.getBundle().getBundleContext();
        TrackedEmf tracked = new TrackedEmf();
        tracked.emf = (EntityManagerFactory)puContext.getService(reference);
        tracked.emSupplier = new EMSupplierImpl(unitName, tracked.emf, coordinator);
        tracked.emSupplierReg = puContext.registerService(EmSupplier.class, tracked.emSupplier,
                                                         getEmSupplierProps(unitName));

        EntityManager emProxy = createProxy(tracked.emSupplier);
        tracked.emProxyReg = puContext.registerService(EntityManager.class, emProxy,
                                                         getEmSupplierProps(unitName));
        
        if (getTransactionType(tracked.emf) == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
            JpaTemplate txManager = new ResourceLocalJpaTemplate(tracked.emSupplier, coordinator);
            tracked.rlTxManagerReg = puContext.registerService(JpaTemplate.class, txManager,
                                                          rlTxManProps(unitName));
        } else {
            tracked.tmTracker = new TMTracker(puContext, tracked.emSupplier, unitName, coordinator);
            tracked.tmTracker.open();
        }
        return tracked;
    }

    /**
     * 
     * @param emf to get type from
     * @return
     */
    private PersistenceUnitTransactionType getTransactionType(EntityManagerFactory emf) {
        try {
            PersistenceUnitTransactionType transactionType = (PersistenceUnitTransactionType) emf.getProperties().get(PersistenceUnitTransactionType.class.getName());
            if (transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
                return PersistenceUnitTransactionType.RESOURCE_LOCAL;
            }
        } catch (Exception e) {
            LOG.warn("Error while determining the transaction type. Falling back to JTA.", e);
        }
        return PersistenceUnitTransactionType.JTA;
    }

    private static Dictionary<String, String> getEmSupplierProps(String unitName) {
        Dictionary<String, String> props = new Hashtable<String, String>(); // NOSONAR
        props.put(JPA_UNIT_NAME, unitName);
        return props;
    }

    private static Dictionary<String, String> rlTxManProps(String unitName) {
        Dictionary<String, String> props = new Hashtable<String, String>(); // NOSONAR
        props.put(JPA_UNIT_NAME, unitName);
        props.put(TMTracker.TRANSACTION_TYPE, "RESOURCE_LOCAL");
        return props;
    }

    @Override
    public void removedService(ServiceReference reference, Object trackedO) {
        TrackedEmf tracked = (TrackedEmf)trackedO;
        if (tracked.tmTracker != null) {
            tracked.tmTracker.close();
        }
        if (tracked.rlTxManagerReg != null) {
            tracked.rlTxManagerReg.unregister();
        }
        tracked.emSupplierReg.unregister();
        tracked.emProxyReg.unregister();
        tracked.emSupplier.close();
        reference.getBundle().getBundleContext().ungetService(reference);
    }
    
    public static EntityManager createProxy(final EmSupplier emSupplier) {
        ClassLoader loader = EntityManager.class.getClassLoader();
        Class<?>[] ifAr = {
            EntityManager.class
        };
        return (EntityManager)Proxy.newProxyInstance(loader, ifAr, new EmProxy(emSupplier));
    }

    static class TrackedEmf {
        ServiceRegistration emProxyReg;
        ServiceRegistration emSupplierReg;
        EMSupplierImpl emSupplier;
        ServiceRegistration rlTxManagerReg;
        EntityManagerFactory emf;
        TMTracker tmTracker;
    }
}
