/*
 * Copyright (C) 2012  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation
 * version 2.1 of the License.
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 */

package org.ow2.jonas.cdi.weld.internal.ejb;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;

import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.jboss.weld.ejb.spi.BusinessInterfaceDescriptor;
import org.jboss.weld.ejb.spi.EjbDescriptor;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.ow2.easybeans.api.Factory;
import org.ow2.easybeans.container.mdb.MDBFactory;
import org.ow2.easybeans.container.session.singleton.SingletonSessionFactory;
import org.ow2.easybeans.container.session.stateful.StatefulSessionFactory;
import org.ow2.easybeans.container.session.stateless.StatelessSessionFactory;

/**
 * This class describes an EJB
 *
 * @author Loic Albertin
 */
public class EZBEjbDescriptor<T> implements EjbDescriptor<T> {

    /**
     * The related EasyBeans {@link Factory}
     */
    private Factory<?, ?> factory;

    /**
     * The bean class
     */
    private Class<T> beanClass;

    /**
     * The local business interfaces descriptors for the bean
     */
    private Collection<BusinessInterfaceDescriptor<?>> localBusinessInterfaceDescriptors;

    /**
     * The remote business interfaces descriptors for the bean
     */
    private Collection<BusinessInterfaceDescriptor<?>> remoteBusinessInterfaceDescriptors;

    /**
     * The bean name
     */
    private String ejbName;

    /**
     * Bean is Stateful
     */
    private boolean isStateful;

    /**
     * Bean is Stateless
     */
    private boolean isStateless;

    /**
     * Bean is Singleton
     */
    private boolean isSingleton;

    /**
     * Bean is Message Driven
     */
    private boolean isMessageDriven;

    /**
     * @param beanDeploymentArchive
     * @param factory
     */
    public EZBEjbDescriptor(BeanDeploymentArchive beanDeploymentArchive, Factory<?, ?> factory) {
        this.factory = factory;

        // Get resource loader to  load classes
        ResourceLoader resourceLoader = beanDeploymentArchive.getServices().get(ResourceLoader.class);

        beanClass = (Class<T>) resourceLoader.classForName(factory.getClassName());

        localBusinessInterfaceDescriptors = new HashSet<BusinessInterfaceDescriptor<?>>();
        for (final String localInterface : factory.getBeanInfo().getLocalInterfaces()) {
            localBusinessInterfaceDescriptors.add(new EZBBusinessInterfaceDescriptor(localInterface, resourceLoader));
        }

        remoteBusinessInterfaceDescriptors = new HashSet<BusinessInterfaceDescriptor<?>>();
        for (final String remoteInterface : factory.getBeanInfo().getRemoteInterfaces()) {
            remoteBusinessInterfaceDescriptors.add(new EZBBusinessInterfaceDescriptor(remoteInterface, resourceLoader));
        }
        ejbName = factory.getBeanInfo().getName();

        isMessageDriven = factory instanceof MDBFactory;
        isStateful = factory instanceof StatefulSessionFactory;
        isSingleton = factory instanceof SingletonSessionFactory;
        isStateless = factory instanceof StatelessSessionFactory;

        //TODO keep trace of Remove methods in beanInfo
    }

    public Class<T> getBeanClass() {
        return beanClass;
    }

    public Collection<BusinessInterfaceDescriptor<?>> getLocalBusinessInterfaces() {
        return localBusinessInterfaceDescriptors;
    }

    public Collection<BusinessInterfaceDescriptor<?>> getRemoteBusinessInterfaces() {
        return remoteBusinessInterfaceDescriptors;
    }

    public String getEjbName() {
        return ejbName;
    }

    public Collection<Method> getRemoveMethods() {
        //TODO keep trace of Remove methods in beanInfo
        return null;
    }

    public boolean isStateless() {
        return isStateless;
    }

    public boolean isSingleton() {
        return isSingleton;
    }

    public boolean isStateful() {
        return isStateful;
    }

    public boolean isMessageDriven() {
        return isMessageDriven;
    }

    public Factory<?, ?> getFactory() {
        return factory;
    }
}
