/*
 *
 * 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 WARRANTIES OR 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.qpid.client;

import static org.apache.qpid.client.AMQConnection.JNDI_ADDRESS_CONNECTION_URL;

import org.apache.qpid.client.util.JMSExceptionHelper;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jndi.ObjectFactory;
import org.apache.qpid.url.URLSyntaxException;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.XAConnection;
import javax.jms.XAConnectionFactory;
import javax.jms.XAQueueConnection;
import javax.jms.XAQueueConnectionFactory;
import javax.jms.XATopicConnection;
import javax.jms.XATopicConnectionFactory;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Hashtable;
import java.util.UUID;


public class AMQConnectionFactory extends AbstractConnectionFactory
                                  implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,
                                             javax.naming.spi.ObjectFactory, Referenceable, XATopicConnectionFactory,
                                             XAQueueConnectionFactory, XAConnectionFactory, Serializable
{
    private static final long serialVersionUID = 1L;

    static
    {
        ClientProperties.ensureIsLoaded();
    }

    protected static final String NO_URL_CONFIGURED = "The connection factory wasn't created with a proper URL, the connection details are empty";
    private final static  ObjectFactory OBJECT_FACTORY = new ObjectFactory();

    private ConnectionURL _connectionDetails;

    // The default constructor is necessary to allow AMQConnectionFactory to be deserialised from JNDI
    public AMQConnectionFactory()
    {
    }

    public AMQConnectionFactory(final String url) throws URLSyntaxException
    {
        if (url == null)
        {
            throw new IllegalArgumentException("url cannot be null");
        }

        _connectionDetails = new AMQConnectionURL(url);
    }

    public AMQConnectionFactory(ConnectionURL url)
    {
        if (url == null)
        {
            throw new IllegalArgumentException("url cannot be null");
        }

        _connectionDetails = url;
    }

    /**
     * @return the virtualPath of the connection details.
     */
    public final String getVirtualPath()
    {
        return _connectionDetails.getVirtualHost();
    }

    public static String getUniqueClientID()
    {
        try
        {
            InetAddress addr = InetAddress.getLocalHost();
            return addr.getHostName() + System.currentTimeMillis();
        }
        catch (UnknownHostException e)
        {
            return "UnknownHost" + UUID.randomUUID();
        }
    }

    public AMQConnection createConnection() throws JMSException
    {
        if(_connectionDetails == null)
        {
            throw new JMSException(NO_URL_CONFIGURED);
        }

        try
        {
            if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals(""))
            {
                _connectionDetails.setClientName(getUniqueClientID());
            }
            return newAMQConnectionInstance(_connectionDetails);
        }
        catch (Exception e)
        {
            throw JMSExceptionHelper.chainJMSException(new JMSException("Error creating connection: " + e.getMessage()),
                                                       e);
        }
    }

    public AMQConnection createConnection(String userName, String password) throws JMSException
    {
        return createConnection(userName, password, null);
    }
    
    public AMQConnection createConnection(String userName, String password, String id) throws JMSException
    {
        if (_connectionDetails != null)
        {
            try
            {
                ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.getURL());
                connectionDetails.setUsername(userName);
                connectionDetails.setPassword(password);
                
                if (id != null && !id.equals(""))
                {
                    connectionDetails.setClientName(id);
                } 
                else if (connectionDetails.getClientName() == null || connectionDetails.getClientName().equals(""))
                {
                    connectionDetails.setClientName(getUniqueClientID());
                }
                return newAMQConnectionInstance(connectionDetails);
            }
            catch (Exception e)
            {
                throw JMSExceptionHelper.chainJMSException(new JMSException("Error creating connection: "
                                                                            + e.getMessage()), e);
            }
        }
        else
        {
            throw new JMSException(NO_URL_CONFIGURED);
        }
    }

    public QueueConnection createQueueConnection() throws JMSException
    {
        return createConnection();
    }

    public QueueConnection createQueueConnection(String username, String password) throws JMSException
    {
        return createConnection(username, password);
    }

    public TopicConnection createTopicConnection() throws JMSException
    {
        return createConnection();
    }

    public TopicConnection createTopicConnection(String username, String password) throws JMSException
    {
        return createConnection(username, password);
    }


    public ConnectionURL getConnectionURL()
    {
        return _connectionDetails;
    }

    public String getConnectionURLString()
    {
        return _connectionDetails.toString();
    }

    //setter necessary to use instances created with the default constructor (which we can't remove)
    public final void setConnectionURLString(String url) throws URLSyntaxException
    {
        _connectionDetails = new AMQConnectionURL(url);
    }

    /**
     * JNDI interface to create objects from References.
     *
     * @param obj  The Reference from JNDI
     * @param name
     * @param ctx
     * @param env
     *
     * @return AMQConnection,AMQTopic,AMQQueue, or AMQConnectionFactory.
     *
     * @throws Exception
     *
     * @deprecated Use {@link ObjectFactory} instead
     */
    @Deprecated
    public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable env) throws Exception
    {
        return OBJECT_FACTORY.getObjectInstance(obj, name, ctx, env);
    }


    public Reference getReference() throws NamingException
    {
        return new Reference(
                AMQConnectionFactory.class.getName(),
                new StringRefAddr(JNDI_ADDRESS_CONNECTION_URL, _connectionDetails.getURL()),
                             ObjectFactory.class.getName(), null);          // factory location
    }

    // ---------------------------------------------------------------------------------------------------
    // the following methods are provided for XA compatibility
    // Those methods are only supported by 0_10 and above 
    // ---------------------------------------------------------------------------------------------------

    /**
     * Creates a XAConnection with the default user identity.
     * <p> The XAConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @return A newly created XAConnection
     * @throws JMSException         If creating the XAConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XAConnection createXAConnection() throws JMSException
    {
        try
        {
            return new XAConnectionImpl(_connectionDetails);
        }
        catch (Exception e)
        {
            throw JMSExceptionHelper.chainJMSException(new JMSException("Error creating connection: " + e.getMessage()),
                                                       e);
        }
    }

    /**
     * Creates a XAConnection with the specified user identity.
     * <p> The XAConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @param username the caller's user name
     * @param password the caller's password
     * @return A newly created XAConnection.
     * @throws JMSException         If creating the XAConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XAConnection createXAConnection(String username, String password) throws JMSException
    {
        if (_connectionDetails != null)
        {
            try
            {
                ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.toString());
                connectionDetails.setUsername(username);
                connectionDetails.setPassword(password);
    
                if (connectionDetails.getClientName() == null || connectionDetails.getClientName().equals(""))
                {
                    connectionDetails.setClientName(getUniqueClientID());
                }
                return new XAConnectionImpl(connectionDetails);
            }
            catch (Exception e)
            {
                throw JMSExceptionHelper.chainJMSException(new JMSException("Error creating XA Connection: "
                                                                            + e.getMessage()), e);
            }
        }
        else
        {
            throw new JMSException(NO_URL_CONFIGURED);
        }        
    }


    /**
     * Creates a XATopicConnection with the default user identity.
     * <p> The XATopicConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @return A newly created XATopicConnection
     * @throws JMSException         If creating the XATopicConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XATopicConnection createXATopicConnection() throws JMSException
    {
        return (XATopicConnection) createXAConnection();
    }

    /**
     * Creates a XATopicConnection with the specified user identity.
     * <p> The XATopicConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @param username the caller's user name
     * @param password the caller's password
     * @return A newly created XATopicConnection.
     * @throws JMSException         If creating the XATopicConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XATopicConnection createXATopicConnection(String username, String password) throws JMSException
    {
         return (XATopicConnection) createXAConnection(username, password);
    }

    /**
     * Creates a XAQueueConnection with the default user identity.
     * <p> The XAQueueConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @return A newly created XAQueueConnection
     * @throws JMSException         If creating the XAQueueConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XAQueueConnection createXAQueueConnection() throws JMSException
    {
       return (XAQueueConnection) createXAConnection();
    }

    /**
     * Creates a XAQueueConnection with the specified user identity.
     * <p> The XAQueueConnection is created in stopped mode. No messages
     * will be delivered until the <code>Connection.start</code> method
     * is explicitly called.
     *
     * @param username the caller's user name
     * @param password the caller's password
     * @return A newly created XAQueueConnection.
     * @throws JMSException         If creating the XAQueueConnection fails due to some internal error.
     * @throws javax.jms.JMSSecurityException If client authentication fails due to an invalid user name or password.
     */
    public XAQueueConnection createXAQueueConnection(String username, String password) throws JMSException
    {
        return (XAQueueConnection) createXAConnection(username, password);
    }

    @Override
    public boolean equals(final Object o)
    {
        if (this == o)
        {
            return true;
        }
        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        final AMQConnectionFactory that = (AMQConnectionFactory) o;

        if (_connectionDetails != null
                ? !_connectionDetails.equals(that._connectionDetails)
                : that._connectionDetails != null)
        {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode()
    {
        return _connectionDetails != null ? _connectionDetails.hashCode() : 0;
    }

    @Override
    public String toString()
    {
        return "AMQConnectionFactory{" +
               "_connectionDetails=" + _connectionDetails +
               '}';
    }
}
