/*
 *
 * 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 java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.url.URLHelper;
import org.apache.qpid.url.URLSyntaxException;

public class BrokerDetails implements Serializable
{
    /*
     * Known URL Options
     * @see ConnectionURL
    */
    public static final String OPTIONS_RETRY = "retries";
    public static final String OPTIONS_CONNECT_TIMEOUT = "connecttimeout";
    public static final String OPTIONS_CONNECT_DELAY = "connectdelay";
    public static final String OPTIONS_HEARTBEAT = "heartbeat";
    private static final String OPTIONS_IDLE_TIMEOUT = "idle_timeout";
    public static final String OPTIONS_SASL_MECHS = "sasl_mechs";
    public static final String OPTIONS_SASL_ENCRYPTION = "sasl_encryption";
    public static final String OPTIONS_SSL = "ssl";
    public static final String OPTIONS_TCP_NO_DELAY = "tcp_nodelay";
    public static final String OPTIONS_SASL_PROTOCOL_NAME = "sasl_protocol";
    public static final String OPTIONS_SASL_SERVER_NAME = "sasl_server";
    public static final String OPTIONS_TRUST_STORE = "trust_store";
    public static final String OPTIONS_TRUST_STORE_PASSWORD = "trust_store_password";
    public static final String OPTIONS_TRUST_STORE_TYPE = "trust_store_type";
    public static final String OPTIONS_KEY_STORE = "key_store";
    public static final String OPTIONS_KEY_STORE_PASSWORD = "key_store_password";
    public static final String OPTIONS_KEY_STORE_TYPE = "key_store_type";
    public static final String OPTIONS_SSL_VERIFY_HOSTNAME = "ssl_verify_hostname";
    public static final String OPTIONS_SSL_CERT_ALIAS = "ssl_cert_alias";
    public static final String OPTIONS_CLIENT_CERT_PRIV_KEY_PATH = "client_cert_priv_key_path";
    public static final String OPTIONS_CLIENT_CERT_PATH = "client_cert_path";
    public static final String OPTIONS_CLIENT_CERT_INTERMEDIARY_CERT_PATH = "client_cert_intermediary_cert_path" ;
    public static final String OPTIONS_TRUSTED_CERTIFICATES_PATH = "trusted_certs_path";

    public static final String OPTIONS_ENCRYPTION_TRUST_STORE = "encryption_trust_store";
    public static final String OPTIONS_ENCRYPTION_TRUST_STORE_PASSWORD = "encryption_trust_store_password";
    public static final String OPTIONS_ENCRYPTION_TRUST_STORE_TYPE = "encryption_trust_store_type";
    public static final String OPTIONS_ENCRYPTION_REMOTE_TRUST_STORE = "encryption_remote_trust_store";
    public static final String OPTIONS_ENCRYPTION_KEY_STORE = "encryption_key_store";
    public static final String OPTIONS_ENCRYPTION_KEY_STORE_PASSWORD = "encryption_key_store_password";
    public static final String OPTIONS_ENCRYPTION_KEY_STORE_TYPE = "encryption_key_store_type";

    static final Set<String> PASSWORD_YIELDING_OPTIONS =
            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
                    OPTIONS_TRUST_STORE_PASSWORD,
                    OPTIONS_KEY_STORE_PASSWORD,
                    OPTIONS_ENCRYPTION_TRUST_STORE_PASSWORD,
                    OPTIONS_ENCRYPTION_KEY_STORE_PASSWORD)));

    public static final int DEFAULT_PORT = 5672;
    public static final String TCP = "tcp";
    public static final String SOCKET = "socket";
    public static final String DEFAULT_TRANSPORT = BrokerDetails.TCP;
    public static final String URL_FORMAT_EXAMPLE =
            "<transport>://<hostname>[:<port Default=\"" + BrokerDetails.DEFAULT_PORT + "\">][?<option>='<value>'[,<option>='<value>']]";
    public static final int DEFAULT_CONNECT_TIMEOUT = 30000;
    public static final boolean USE_SSL_DEFAULT = false;
    // pulled these properties from the new BrokerDetails class in the qpid package
    public static final String PROTOCOL_TCP = "tcp";
    public static final String PROTOCOL_TLS = "tls";
    public static final String VIRTUAL_HOST = "virtualhost";
    public static final String CLIENT_ID = "client_id";
    public static final String USERNAME = "username";
    public static final String PASSWORD = "password";
    private static final long serialVersionUID = 8762219750300869355L;
    private String _host;
    private int _port;
    private String _transport;

    private Map<String, String> _options = new HashMap<String, String>();
    private AMQConnectionURL _connectionUrl;

    public BrokerDetails(BrokerDetails details)
    {
        _host = details.getHost();
        _port = details.getPort();
        _transport = details.getTransport();
        _options = new HashMap<>(details._options);
        _connectionUrl = details._connectionUrl;
    }

    public BrokerDetails(){}
    
    public BrokerDetails(String url) throws URLSyntaxException
    {        
      
        // URL should be of format tcp://host:port?option='value',option='value'
        try
        {
            URI connection = new URI(url);

            String transport = connection.getScheme();

            // Handles some defaults to minimise changes to existing broker URLS e.g. localhost
            if (transport != null)
            {
                //todo this list of valid transports should be enumerated somewhere
                if (!(transport.equalsIgnoreCase(BrokerDetails.TCP) || transport.equalsIgnoreCase(BrokerDetails.SOCKET)))
                {
                    if (transport.equalsIgnoreCase("localhost"))
                    {
                        connection = new URI(DEFAULT_TRANSPORT + "://" + url);
                        transport = connection.getScheme();
                    }
                    else
                    {
                        if (url.charAt(transport.length()) == ':' && url.charAt(transport.length() + 1) != '/')
                        {
                            //Then most likely we have a host:port value
                            connection = new URI(DEFAULT_TRANSPORT + "://" + url);
                            transport = connection.getScheme();
                        }
                        else
                        {
                            throw URLHelper.parseError(0, transport.length(), "Unknown transport", url);
                        }
                    }
                }
                else if (url.indexOf("//") == -1)
                {
                    throw new URLSyntaxException(url, "Missing '//' after the transport In broker URL",transport.length()+1,1);
                }
            }
            else
            {
                //Default the transport
                connection = new URI(DEFAULT_TRANSPORT + "://" + url);
                transport = connection.getScheme();
            }

            if (transport == null)
            {
                throw URLHelper.parseError(-1, "Unknown transport in broker URL:'"
                        + url + "' Format: " + URL_FORMAT_EXAMPLE, "");
            }

            setTransport(transport);

            String host = connection.getHost();

            // Fix for Java 1.5
            if (host == null)
            {
                host = "";
                
                String auth = connection.getAuthority();
                if (auth != null)
                {
                    // contains both host & port myhost:5672                
                    if (auth.contains(":"))
                    {
                        host = auth.substring(0,auth.indexOf(":"));
                    }
                    else
                    {
                        host = auth;
                    }
                }

            }

            setHost(host);

            int port = connection.getPort();

            if (port == -1)
            {
                // Fix for when there is port data but it is not automatically parseable by getPort().
                String auth = connection.getAuthority();

                if (auth != null && auth.contains(":"))
                {
                    int start = auth.indexOf(":") + 1;
                    int end = start;
                    boolean looking = true;
                    boolean found = false;
                    // Throw an URL exception if the port number is not specified
                    if (start == auth.length())
                    {
                        throw URLHelper.parseError(connection.toString().indexOf(auth) + end - 1,
                                connection.toString().indexOf(auth) + end, "Port number must be specified",
                                connection.toString());
                    }
                    //Walk the authority looking for a port value.
                    while (looking)
                    {
                        try
                        {
                            end++;
                            Integer.parseInt(auth.substring(start, end));

                            if (end >= auth.length())
                            {
                                looking = false;
                                found = true;
                            }
                        }
                        catch (NumberFormatException nfe)
                        {
                            looking = false;
                        }

                    }
                    if (found)
                    {
                        setPort(Integer.parseInt(auth.substring(start, end)));
                    }
                    else
                    {
                        throw URLHelper.parseError(connection.toString().indexOf(connection.getAuthority()) + end - 1,
                                             "Illegal character in port number", connection.toString());
                    }

                }
                else
                {
                    setPort(DEFAULT_PORT);
                }
            }
            else
            {
                setPort(port);
            }

            String queryString = connection.getQuery();

            URLHelper.parseOptions(_options, queryString);

            //Fragment is #string (not used)
        }
        catch (URISyntaxException uris)
        {
            if (uris instanceof URLSyntaxException)
            {
                throw(URLSyntaxException) uris;
            }

            throw URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput());
        }
    }

    public BrokerDetails(String host, int port)
    {
        _host = host;
        _port = port;
    }

    public String getHost()
    {
        return _host;
    }

    public void setHost(String _host)
    {
        this._host = _host;
    }

    public int getPort()
    {
        return _port;
    }

    public void setPort(int _port)
    {
        this._port = _port;
    }

    public String getTransport()
    {
        return _transport;
    }

    public void setTransport(String _transport)
    {
        this._transport = _transport;
    }


    public String getProperty(String key)
    {
        String value = _options.get(key);
        if(value == null && _connectionUrl != null)
        {
            value = _connectionUrl.getOption(key);
        }
        return value;
    }

    public void setProperty(String key, String value)
    {
        _options.put(key, value);
    }

    private int lookupConnectTimeout()
    {
        if (_options.containsKey(OPTIONS_CONNECT_TIMEOUT))
        {
            try
            {
                return Integer.parseInt(_options.get(OPTIONS_CONNECT_TIMEOUT));
            }
            catch (NumberFormatException nfe)
            {
                //Do nothing as we will use the default below.
            }
        }

        return BrokerDetails.DEFAULT_CONNECT_TIMEOUT;
    }
    
    public boolean getBooleanProperty(String propName)
    {
        return getBooleanProperty(propName, false);
    }
    
    public boolean getBooleanProperty(String propName, boolean defaultValue)
    {
    	if (_options.containsKey(propName))
    	{
            if (_options.get(propName).equalsIgnoreCase("false"))
            {
                return false;
            }
            else if (_options.get(propName).equalsIgnoreCase("true"))
            {
                return true;
            }
            else
            {
               return defaultValue;
            }
    	}
    	else
    	{
    		return defaultValue;
    	}
    }    

    private int getIntegerProperty(String key)
    {
        String stringValue = getProperty(key);
        try
        {
            return Integer.parseInt(stringValue);
        }
        catch (NumberFormatException e)
        {
            throw new IllegalArgumentException("Cannot parse key " + key + " with value '" + stringValue + "' as integer.", e);
        }
    }

    public String toString()
    {
        StringBuffer sb = new StringBuffer();

        sb.append(_transport);
        sb.append("://");
        sb.append(_host);
        sb.append(':');
        sb.append(_port);

        sb.append(printOptionsURL());

        return sb.toString();
    }

    public boolean equals(Object o)
    {
        if (this == o)
        {
            return true;
        }

        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        BrokerDetails bd = (BrokerDetails) o;

        return _host.toLowerCase().equals(bd.getHost() == null ? null : bd.getHost().toLowerCase()) &&
               (_port == bd.getPort()) &&
               _transport.toLowerCase().equals(bd.getTransport() == null ? null : bd.getTransport().toLowerCase());
        //TODO do we need to compare all the options as well?
    }

    @Override
    public int hashCode()
    {
        int result = _host != null ? _host.toLowerCase().hashCode() : 0;
        result = 31 * result + _port;
        result = 31 * result + (_transport != null ? _transport.toLowerCase().hashCode() : 0);
        return result;
    }

    private String printOptionsURL()
    {
        return URLHelper.printOptions(_options, PASSWORD_YIELDING_OPTIONS);
    }

    public static String checkTransport(String broker)
    {
        if ((!broker.contains("://")))
        {
            return "tcp://" + broker;
        }
        else
        {
            return broker;
        }
    }

    public ConnectionSettings buildConnectionSettings()
    {
        ConnectionSettings conSettings = new ConnectionSettings();

        conSettings.setHost(getHost());
        conSettings.setPort(getPort());
        conSettings.setTransport(getTransport());

        // ------------ sasl options ---------------
        if (getProperty(BrokerDetails.OPTIONS_SASL_MECHS) != null)
        {
            conSettings.setSaslMechs(
                    getProperty(BrokerDetails.OPTIONS_SASL_MECHS));
        }

        // Sun SASL Kerberos client uses the
        // protocol + servername as the service key.

        if (getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME) != null)
        {
            conSettings.setSaslProtocol(
                    getProperty(BrokerDetails.OPTIONS_SASL_PROTOCOL_NAME));
        }


        if (getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME) != null)
        {
            conSettings.setSaslServerName(
                    getProperty(BrokerDetails.OPTIONS_SASL_SERVER_NAME));
        }

        conSettings.setUseSASLEncryption(
                getBooleanProperty(BrokerDetails.OPTIONS_SASL_ENCRYPTION));

        // ------------- ssl options ---------------------
        conSettings.setUseSSL(getBooleanProperty(BrokerDetails.OPTIONS_SSL));

        if (getProperty(BrokerDetails.OPTIONS_TRUST_STORE) != null)
        {
            conSettings.setTrustStorePath(
                    getProperty(BrokerDetails.OPTIONS_TRUST_STORE));
        }

        if (getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD) != null)
        {
            conSettings.setTrustStorePassword(
                    getProperty(BrokerDetails.OPTIONS_TRUST_STORE_PASSWORD));
        }

        if (getProperty(BrokerDetails.OPTIONS_TRUST_STORE_TYPE) != null)
        {
            conSettings.setTrustStoreType(
                    getProperty(BrokerDetails.OPTIONS_TRUST_STORE_TYPE));
        }

        if (getProperty(BrokerDetails.OPTIONS_KEY_STORE) != null)
        {
            conSettings.setKeyStorePath(
                    getProperty(BrokerDetails.OPTIONS_KEY_STORE));
        }

        if (getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD) != null)
        {
            conSettings.setKeyStorePassword(
                    getProperty(BrokerDetails.OPTIONS_KEY_STORE_PASSWORD));
        }

        if (getProperty(BrokerDetails.OPTIONS_KEY_STORE_TYPE) != null)
        {
            conSettings.setKeyStoreType(
                    getProperty(BrokerDetails.OPTIONS_KEY_STORE_TYPE));
        }

        if (getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS) != null)
        {
            conSettings.setCertAlias(
                    getProperty(BrokerDetails.OPTIONS_SSL_CERT_ALIAS));
        }

        if (getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_PRIV_KEY_PATH) != null)
        {
            conSettings.setClientCertificatePrivateKeyPath(
                    getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_PRIV_KEY_PATH));
        }

        if (getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_PATH) != null)
        {
            conSettings.setClientCertificatePath(
                    getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_PATH));
        }

        if (getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_INTERMEDIARY_CERT_PATH) != null)
        {
            conSettings.setClientCertificateIntermediateCertsPath(
                    getProperty(BrokerDetails.OPTIONS_CLIENT_CERT_INTERMEDIARY_CERT_PATH));
        }

        if (getProperty(BrokerDetails.OPTIONS_TRUSTED_CERTIFICATES_PATH) != null)
        {
            conSettings.setTrustedCertificatesFile(
                    getProperty(BrokerDetails.OPTIONS_TRUSTED_CERTIFICATES_PATH));
        }
        // ----------------------------

        boolean defaultSSLVerifyHostName = Boolean.parseBoolean(
                System.getProperty(ClientProperties.CONNECTION_OPTION_SSL_VERIFY_HOST_NAME,
                    String.valueOf(ClientProperties.DEFAULT_CONNECTION_OPTION_SSL_VERIFY_HOST_NAME)));
        conSettings.setVerifyHostname(getBooleanProperty(BrokerDetails.OPTIONS_SSL_VERIFY_HOSTNAME, defaultSSLVerifyHostName ));

        // ----------------------------

        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE) != null)
        {
            conSettings.setEncryptionKeyStorePath(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE));
        }

        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE_PASSWORD) != null)
        {
            conSettings.setEncryptionKeyStorePassword(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE_PASSWORD));
        }

        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE_TYPE) != null)
        {
            conSettings.setEncryptionKeyStoreType(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_KEY_STORE_TYPE));
        }

        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE) != null)
        {
            conSettings.setEncryptionTrustStorePath(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE));
        }

        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE_PASSWORD) != null)
        {
            conSettings.setEncryptionTrustStorePassword(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE_PASSWORD));
        }


        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE_TYPE) != null)
        {
            conSettings.setEncryptionTrustStoreType(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_TRUST_STORE_TYPE));
        }


        if (getProperty(BrokerDetails.OPTIONS_ENCRYPTION_REMOTE_TRUST_STORE) != null)
        {
            conSettings.setEncryptionRemoteTrustStoreName(
                    getProperty(BrokerDetails.OPTIONS_ENCRYPTION_REMOTE_TRUST_STORE));
        }

        // ----------------------------

        if (getProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY) != null)
        {
            conSettings.setTcpNodelay(
                    getBooleanProperty(BrokerDetails.OPTIONS_TCP_NO_DELAY,true));
        }

        conSettings.setConnectTimeout(lookupConnectTimeout());

        if (getProperty(BrokerDetails.OPTIONS_HEARTBEAT) != null)
        {
            conSettings.setHeartbeatInterval(getIntegerProperty(BrokerDetails.OPTIONS_HEARTBEAT));
        }
        else if (getProperty(BrokerDetails.OPTIONS_IDLE_TIMEOUT) != null)
        {
            conSettings.setHeartbeatInterval(getIntegerProperty(BrokerDetails.OPTIONS_IDLE_TIMEOUT) / 1000);
        }

        return conSettings;
    }

    public void setConnectionUrl(final AMQConnectionURL connectionUrl)
    {
        _connectionUrl = connectionUrl;
    }
}
