/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2012 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 *  $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.datasource.internal;

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

import javax.naming.Context;
import javax.naming.LinkRef;

import org.ow2.easybeans.api.bean.info.IBeanInfo;
import org.ow2.easybeans.api.event.naming.EZBJavaContextNamingEvent;
import org.ow2.jonas.datasource.DataSourceService;
import org.ow2.util.ee.metadata.common.api.struct.IJAnnotationSqlDataSourceDefinition;
import org.ow2.util.event.api.EventPriority;
import org.ow2.util.event.api.IEvent;
import org.ow2.util.event.api.IEventListener;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
 * @author Loic Albertin
 */
public class DSDefinitionExtensionListener implements IEventListener {

    private static Log logger = LogFactory.getLog(DSDefinitionExtensionListener.class);

    private DataSourceService dataSourceService;

    public DSDefinitionExtensionListener(DataSourceService dataSourceService) {
        this.dataSourceService = dataSourceService;
    }

    public void handle(IEvent event) {
        EZBJavaContextNamingEvent javaContextNamingEvent = (EZBJavaContextNamingEvent) event;
        IBeanInfo beanInfo = javaContextNamingEvent.getFactory().getBeanInfo();
        Context context = javaContextNamingEvent.getJavaContext();


        for (IJAnnotationSqlDataSourceDefinition dataSourceDefinition : beanInfo.getDataSourceDefinitions()) {
            String normalizedDataSourceName = dataSourceDefinition.getName();
            if (normalizedDataSourceName.startsWith("java:")) {
                normalizedDataSourceName = normalizedDataSourceName.replaceFirst("java:", "");
            } else {
                normalizedDataSourceName = "comp/env/" + normalizedDataSourceName;
            }
            try {

                Map<String, String> properties = new HashMap<String, String>();
                for (int i = 0; i < dataSourceDefinition.getProperties().length; i++) {
                    String prop = dataSourceDefinition.getProperties()[i];
                    String[] property = prop.split("=");
                    if (property.length == 2) {
                        properties.put(property[0], property[1]);
                    }
                }
                final String globalJndiName = dataSourceService
                        .deployDataSource(dataSourceDefinition.getClassName(), dataSourceDefinition.getDescription(),
                                dataSourceDefinition.getUrl(), dataSourceDefinition.getUser(), dataSourceDefinition.getPassword(),
                                dataSourceDefinition.getDatabaseName(), dataSourceDefinition.getPortNumber(),
                                dataSourceDefinition.getServerName(), dataSourceDefinition.getIsolationLevel(),
                                dataSourceDefinition.isTransactional(), dataSourceDefinition.getInitialPoolSize(),
                                dataSourceDefinition.getMaxPoolSize(), dataSourceDefinition.getMinPoolSize(),
                                dataSourceDefinition.getMaxIdleTime(), dataSourceDefinition.getMaxStatements(),
                                dataSourceDefinition.getLoginTimeout(), properties);


                context.rebind(normalizedDataSourceName, new LinkRef(globalJndiName));
            } catch (Exception e) {
                logger.error("Unable to define data source {0}", dataSourceDefinition.getName(), e);
            }
        }

    }

    public boolean accept(IEvent event) {
        if (event instanceof EZBJavaContextNamingEvent) {
            EZBJavaContextNamingEvent javaContextNamingEvent = (EZBJavaContextNamingEvent) event;

            // source/event-provider-id attribute is used to filter the destination
            if ("java:".equals(javaContextNamingEvent.getEventProviderId())) {
                return true;
            }
        }
        return false;
    }

    public EventPriority getPriority() {
        return EventPriority.SYNC_NORM;
    }

}
