/* 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.url;

import org.apache.qpid.client.BrokerDetails;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

/**
 * The format Qpid URL is based on the AMQP one. The grammar is as follows:
 * <p>
 * <p>{@literal qpid_url          = "qpid:" [client_props "@"] port_addr_list ["/" future-parameters] }
 * <p>{@literal port_addr_list 	 = [port_addr ","]* port_addr }
 * <p>{@literal port_addr         = tcp_port_addr | tls_prot_addr | future_prot_addr }
 * <p>{@literal tcp_port_addr     = tcp_id tcp_addr }
 * <p>{@literal tcp_id            = "tcp:" | "" }
 * <p>{@literal tcp_addr          = host [":" port] }
 * <p>{@literal host              = <as per http://www.apps.ietf.org/> }
 * <p>{@literal port              = number }
 * <p>{@literal tls_prot_addr     = tls_id tls_addr }
 * <p>{@literal tls_id            = "tls:" | "" }
 * <p>{@literal tls_addr          = host [":" port] }
 * <p>{@literal future_prot_addr  = future_prot_id future_prot_addr }
 * <p>{@literal future_prot_id    = <placeholder, must end in ":". Example "sctp:"> }
 * <p>{@literal future_prot_addr  = <placeholder, protocl-specific address> }
 * <p>{@literal future_parameters = <placeholder, not used in failover addresses> }
 * <p>{@literal client_props      = [client_prop ";"]*  client_prop }
 * <p>{@literal client_prop       = prop "=" val }
 * <p>{@literal prop              = chars as per <as per http://www.apps.ietf.org/> }
 * <p>{@literal val               = valid as per <as per http://www.apps.ietf.org/> }
 * <p>
 * Ex:
 * <p>
 * {@literal qpid:virtualhost=tcp:host-foo,test,client_id=foo@tcp:myhost.com:5672,virtualhost=prod;
 * keystore=/opt/keystore@client_id2@tls:mysecurehost.com:5672 }
 */
public class URLParser_0_10
{
    private static final char[] URL_START_SEQ = new char[]{'q', 'p', 'i', 'd', ':'};
    private static final char PROPERTY_EQUALS_CHAR = '=';
    private static final char PROPERTY_SEPARATOR_CHAR = ';';
    private static final char ADDRESS_SEPERATOR_CHAR = ',';

    private static final char TRANSPORT_HOST_SEPARATOR_CHAR = ':';
    private static final char HOST_PORT_SEPARATOR_CHAR = ':';
    private static final char AT_CHAR = '@';
    private static final char END_OF_URL_MARKER = '^';

    enum URLParserState
    {
        QPID_URL_START,
        ADDRESS_START,
        PROPERTY_NAME,
        PROPERTY_EQUALS,
        PROPERTY_VALUE,
        PROPERTY_SEPARATOR,
        AT_CHAR,
        TRANSPORT,
        TRANSPORT_HOST_SEPARATOR,
        HOST,
        HOST_PORT_SEPARATOR,
        PORT,
        ADDRESS_END,
        ADDRESS_SEPERATOR,
        QPID_URL_END,
        ERROR
    }

    //-- Constructors

    private char[] _url;
    private List<BrokerDetails> _brokerDetailList = new ArrayList<BrokerDetails>();
    private String _error;
    private int _index = 0;
    private BrokerDetails _currentBroker;
    private String _currentPropName;
    private boolean _endOfURL = false;
    private URLParserState _currentParserState;

    public URLParser_0_10(String url) throws MalformedURLException
    {
        _url = (url + END_OF_URL_MARKER).toCharArray();
        _endOfURL = false;
        _currentParserState = URLParserState.QPID_URL_START;
        URLParserState prevState = _currentParserState; // for error handling
        try
        {
            while (_currentParserState != URLParserState.ERROR && _currentParserState != URLParserState.QPID_URL_END)
            {
                prevState = _currentParserState;
                _currentParserState = next();
            }

            if (_currentParserState == URLParserState.ERROR)
            {
                _error =
                        "Invalid URL format [current_state = " + prevState + ", broker details parsed so far " + _currentBroker + " ] error at (" + _index + ") due to " + _error;
                MalformedURLException ex;
                ex = new MalformedURLException(_error);
                throw ex;
            }
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            _error = "Invalid URL format [current_state = " + prevState + ", broker details parsed so far " + _currentBroker + " ] error at (" + _index + ")";
            MalformedURLException ex = new MalformedURLException(_error);
            throw ex;
        }
    }

    //-- interface QpidURL
    public List<BrokerDetails> getAllBrokerDetails()
    {
        return _brokerDetailList;
    }

    public String getURL()
    {
        return new String(_url);
    }

    private URLParserState next()
    {
        switch (_currentParserState)
        {
            case QPID_URL_START:
                return checkSequence(URL_START_SEQ, URLParserState.ADDRESS_START);
            case ADDRESS_START:
                return startAddress();
            case PROPERTY_NAME:
                return extractPropertyName();
            case PROPERTY_EQUALS:
                _index++; // skip the equal sign
                return URLParserState.PROPERTY_VALUE;
            case PROPERTY_VALUE:
                return extractPropertyValue();
            case PROPERTY_SEPARATOR:
                _index++; // skip ","
                return URLParserState.PROPERTY_NAME;
            case AT_CHAR:
                _index++; // skip the @ sign
                return URLParserState.TRANSPORT;
            case TRANSPORT:
                return extractTransport();
            case TRANSPORT_HOST_SEPARATOR:
                _index++; // skip ":"
                return URLParserState.HOST;
            case HOST:
                return extractHost();
            case HOST_PORT_SEPARATOR:
                _index++; // skip ":"
                return URLParserState.PORT;
            case PORT:
                return extractPort();
            case ADDRESS_END:
                return endAddress();
            case ADDRESS_SEPERATOR:
                _index++; // skip ","
                return URLParserState.ADDRESS_START;
            default:
                return URLParserState.ERROR;
        }
    }

    private URLParserState checkSequence(char[] expected, URLParserState nextPart)
    {
        for (char expectedChar : expected)
        {
            if (expectedChar != _url[_index])
            {
                _error = "Excepted (" + expectedChar + ") at position " + _index + ", got (" + _url[_index] + ")";
                return URLParserState.ERROR;
            }
            _index++;
        }
        return nextPart;
    }

    private URLParserState startAddress()
    {
        _currentBroker = new BrokerDetails();

        for (int j = _index; j < _url.length; j++)
        {
            if (_url[j] == PROPERTY_EQUALS_CHAR)
            {
                return URLParserState.PROPERTY_NAME;
            }
            else if (_url[j] == ADDRESS_SEPERATOR_CHAR)
            {
                return URLParserState.TRANSPORT;
            }
        }
        return URLParserState.TRANSPORT;
    }

    private URLParserState endAddress()
    {
        _brokerDetailList.add(_currentBroker);
        if (_endOfURL)
        {
            return URLParserState.QPID_URL_END;
        }
        else
        {
            return URLParserState.ADDRESS_SEPERATOR;
        }
    }

    private URLParserState extractPropertyName()
    {
        StringBuilder b = new StringBuilder();
        char next = _url[_index];
        while (next != PROPERTY_EQUALS_CHAR && next != AT_CHAR)
        {
            b.append(next);
            next = _url[++_index];
        }
        _currentPropName = b.toString();
        if (_currentPropName.trim().equals(""))
        {
            _error = "Property name cannot be empty";
            return URLParserState.ERROR;
        }
        else if (next == PROPERTY_EQUALS_CHAR)
        {
            return URLParserState.PROPERTY_EQUALS;
        }
        else
        {
            return URLParserState.AT_CHAR;
        }
    }

    private URLParserState extractPropertyValue()
    {
        StringBuilder b = new StringBuilder();
        char next = _url[_index];
        while (next != PROPERTY_SEPARATOR_CHAR && next != AT_CHAR)
        {
            b.append(next);
            next = _url[++_index];
        }
        String propValue = b.toString();
        if (propValue.trim().equals(""))
        {
            _error = "Property values cannot be empty";
            return URLParserState.ERROR;
        }
        else
        {
            _currentBroker.setProperty(_currentPropName, propValue);
            if (next == PROPERTY_SEPARATOR_CHAR)
            {
                return URLParserState.PROPERTY_SEPARATOR;
            }
            else
            {
                return URLParserState.AT_CHAR;
            }
        }
    }

    private URLParserState extractTransport()
    {
        String transport = buildUntil(TRANSPORT_HOST_SEPARATOR_CHAR);
        if (transport.trim().equals(""))
        {
            _error = "Transport cannot be empty";
            return URLParserState.ERROR;
        }
        else if (!(transport.trim().equals(BrokerDetails.PROTOCOL_TCP) || transport.trim()
                .equals(BrokerDetails.PROTOCOL_TLS)))
        {
            _error = "Transport cannot be " + transport + " value must be tcp or tls";
            return URLParserState.ERROR;
        }
        else
        {
            _currentBroker.setTransport(transport);
            return URLParserState.TRANSPORT_HOST_SEPARATOR;
        }
    }

    private URLParserState extractHost()
    {
        char nextSep = 'c';
        String host;
        URLParserState nextState;

        for (int i = _index; i < _url.length; i++)
        {
            if (_url[i] == HOST_PORT_SEPARATOR_CHAR)
            {
                nextSep = HOST_PORT_SEPARATOR_CHAR;
                break;
            }
            else if (_url[i] == ADDRESS_SEPERATOR_CHAR)
            {
                nextSep = ADDRESS_SEPERATOR_CHAR;
                break;
            }
        }

        if (nextSep == HOST_PORT_SEPARATOR_CHAR)
        {
            host = buildUntil(HOST_PORT_SEPARATOR_CHAR);
            nextState = URLParserState.HOST_PORT_SEPARATOR;
        }
        else if (nextSep == ADDRESS_SEPERATOR_CHAR)
        {
            host = buildUntil(ADDRESS_SEPERATOR_CHAR);
            nextState = URLParserState.ADDRESS_END;
        }
        else
        {
            host = buildUntil(END_OF_URL_MARKER);
            nextState = URLParserState.ADDRESS_END;
            _endOfURL = true;
        }

        if (host.trim().equals(""))
        {
            _error = "Host cannot be empty";
            return URLParserState.ERROR;
        }
        else
        {
            _currentBroker.setHost(host);
            return nextState;
        }
    }


    private URLParserState extractPort()
    {

        StringBuilder b = new StringBuilder();
        try
        {
            char next = _url[_index];
            while (next != ADDRESS_SEPERATOR_CHAR && next != END_OF_URL_MARKER )
            {
                b.append(next);
                next = _url[++_index];
            }
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            _endOfURL = true;
        }
        String portStr = b.toString();
        if (portStr.trim().equals(""))
        {
            _error = "Host cannot be empty";
            return URLParserState.ERROR;
        }
        else
        {
            try
            {
                int port = Integer.parseInt(portStr);
                _currentBroker.setPort(port);
                if( _url[_index] == END_OF_URL_MARKER )
                {
                    _endOfURL = true;
                }
                return URLParserState.ADDRESS_END;
            }
            catch (NumberFormatException e)
            {
                _error = "Illegal number for port";
                return URLParserState.ERROR;
            }
        }
    }

    private String buildUntil(char c)
    {
        StringBuilder b = new StringBuilder();
        char next = _url[_index];
        while (next != c)
        {
            b.append(next);
            next = _url[++_index];
        }
        return b.toString();
    }

    public static void main(String[] args)
    {
        String testurl = "qpid:password=pass;username=name@tcp:test1";
        try
        {
            URLParser_0_10 impl = new URLParser_0_10(testurl);
            for (BrokerDetails d : impl.getAllBrokerDetails())
            {
                System.out.println(d);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
