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


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class BindingURLParser
{
    private static final char PROPERTY_EQUALS_CHAR = '=';
    private static final char PROPERTY_SEPARATOR_CHAR = '&';
    private static final char ALTERNATIVE_PROPERTY_SEPARATOR_CHAR = ',';
    private static final char FORWARD_SLASH_CHAR = '/';
    private static final char QUESTION_MARK_CHAR = '?';
    private static final char SINGLE_QUOTE_CHAR = '\'';
    private static final char COLON_CHAR = ':';
    private static final char END_OF_URL_MARKER_CHAR = '%';

    private static final Logger _logger = LoggerFactory.getLogger(BindingURLParser.class);

    private char[] _url;
    private AMQBindingURL _bindingURL;
    private BindingURLParserState _currentParserState;
    private String _error;
    private int _index = 0;
    private String _currentPropName;
    private Map<String,Object> _options;


    public BindingURLParser()
    {
    }

    //<exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']*
    public void parse(String url, AMQBindingURL bindingURL)  throws URISyntaxException
    {
        _url = (url + END_OF_URL_MARKER_CHAR).toCharArray();
        _bindingURL = bindingURL;
        _currentParserState = BindingURLParserState.BINDING_URL_START;
        BindingURLParserState prevState = _currentParserState;
        _index = 0;
        _currentPropName = null;
        _error = null;
        _options = new HashMap<>();

        try
        {
            while (_currentParserState != BindingURLParserState.ERROR && _currentParserState != BindingURLParserState.BINDING_URL_END)
            {
                prevState = _currentParserState;
                _currentParserState = next();
            }

            if (_currentParserState == BindingURLParserState.ERROR)
            {
                _error =
                        "Invalid URL format [current_state = " + prevState + ", details extracted so far " + _bindingURL + " ] error at (" + _index + ") due to " + _error;
                _logger.debug(_error);
                URISyntaxException ex;
                ex = new URISyntaxException(markErrorLocation(),"Error occurred while parsing URL",_index);
                throw ex;
            }

            processOptions();
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
                _error = "Invalid URL format [current_state = " + prevState + ", details parsed so far " + _bindingURL + " ] error at (" + _index + ")";
                URISyntaxException ex = new URISyntaxException(markErrorLocation(),"Error occurred while parsing URL",_index);
                ex.initCause(e);
                throw ex;
        }
    }

    enum BindingURLParserState
    {
        BINDING_URL_START,
        EXCHANGE_CLASS,
        COLON_CHAR,
        HIERARCHY_PREFIX,
        EXCHANGE_NAME,
        EXCHANGE_SEPERATOR_CHAR,
        DESTINATION,
        DESTINATION_SEPERATOR_CHAR,
        QUEUE_NAME,
        QUESTION_MARK_CHAR,
        PROPERTY_NAME,
        PROPERTY_EQUALS,
        START_PROPERTY_VALUE,
        PROPERTY_VALUE,
        END_PROPERTY_VALUE,
        PROPERTY_SEPARATOR,
        BINDING_URL_END,
        ERROR
    }

    /**
     * I am fully ware that there are few optimizations
     * that can speed up things a wee bit. But I have opted
     * for readability and maintainability at the expense of
     * speed, as speed is not a critical factor here.
     *
     * One can understand the full parse logic by just looking at this method.
     */
    private BindingURLParserState next()
    {
        switch (_currentParserState)
        {
            case BINDING_URL_START:
                return extractExchangeClass();
            case COLON_CHAR:
                _index++; //skip ":"
                return BindingURLParserState.HIERARCHY_PREFIX;
            case HIERARCHY_PREFIX:
                return consumeHierarchyPrefix();
            case EXCHANGE_NAME:
                return extractExchangeName();
            case EXCHANGE_SEPERATOR_CHAR:
                _index++; // skip '/'
                return BindingURLParserState.DESTINATION;
            case DESTINATION:
                return extractDestination();
            case DESTINATION_SEPERATOR_CHAR:
                _index++; // skip '/'
                return BindingURLParserState.QUEUE_NAME;
            case QUEUE_NAME:
                return extractQueueName();
            case QUESTION_MARK_CHAR:
                _index++; // skip '?'
                return BindingURLParserState.PROPERTY_NAME;
            case PROPERTY_NAME:
                return extractPropertyName();
            case PROPERTY_EQUALS:
                _index++; // skip the equal sign
                return BindingURLParserState.START_PROPERTY_VALUE;
            case START_PROPERTY_VALUE:
                _index++; // skip the '\''
                return BindingURLParserState.PROPERTY_VALUE;
            case PROPERTY_VALUE:
                return extractPropertyValue();
            case END_PROPERTY_VALUE:
                _index ++;
                return checkEndOfURL();
            case PROPERTY_SEPARATOR:
                _index++; // skip '&'
                return BindingURLParserState.PROPERTY_NAME;
            default:
                return BindingURLParserState.ERROR;
        }
    }

    private BindingURLParserState extractExchangeClass()
    {
        char nextChar = _url[_index];

        StringBuilder builder = new StringBuilder();
        while (nextChar != COLON_CHAR && nextChar != END_OF_URL_MARKER_CHAR)
        {
            builder.append(nextChar);
            _index++;
            nextChar = _url[_index];
        }

        // normal use case
        if (nextChar == COLON_CHAR)
        {
            if (builder.length() == 0)
            {
                _error = "Exchange class is absent";
                return BindingURLParserState.ERROR;
            }
            _bindingURL.setExchangeClass(builder.toString());
            return BindingURLParserState.COLON_CHAR;
        }
        else
        {
            return BindingURLParserState.ERROR;
        }
    }

    private BindingURLParserState consumeHierarchyPrefix()
    {
        char nextChar;
        int loop = 0;
        do
        {
            nextChar = _url[_index++];
            loop++;
        }
        while (nextChar == FORWARD_SLASH_CHAR && loop < 2 );

        if (nextChar == FORWARD_SLASH_CHAR)
        {
            return BindingURLParserState.EXCHANGE_NAME;
        }
        else
        {
            _error = "Unexpected character '" + nextChar + "' encountered when expecting hierarchy prefix '/'";
            return BindingURLParserState.ERROR;
        }
    }

    private BindingURLParserState extractExchangeName()
    {
        char nextChar = _url[_index];
        StringBuilder builder = new StringBuilder();
        while (nextChar != FORWARD_SLASH_CHAR)
        {
            builder.append(nextChar);
            _index++;
            nextChar = _url[_index];
        }

        _bindingURL.setExchangeName(builder.toString());
        return BindingURLParserState.EXCHANGE_SEPERATOR_CHAR;
    }

    private BindingURLParserState extractDestination()
    {
        char nextChar = _url[_index];

        //The destination is and queue name are both optional
        // This is checking for the case where both are not specified.
        if (nextChar == QUESTION_MARK_CHAR)
        {
            return BindingURLParserState.QUESTION_MARK_CHAR;
        }

        StringBuilder builder = new StringBuilder();
        while (nextChar != FORWARD_SLASH_CHAR && nextChar != QUESTION_MARK_CHAR)
        {
            builder.append(nextChar);
            _index++;
            nextChar = _url[_index];
        }

        // This is the case where the destination is explicitly stated.
        // ex direct://amq.direct/myDest/myQueue?option1='1' ... OR
        // direct://amq.direct//myQueue?option1='1' ...
        if (nextChar == FORWARD_SLASH_CHAR)
        {
            _bindingURL.setDestinationName(builder.toString());
            return BindingURLParserState.DESTINATION_SEPERATOR_CHAR;
        }
        // This is the case where destination is not explicitly stated.
        // ex direct://amq.direct/myQueue?option1='1' ...
        else
        {
            _bindingURL.setQueueName(builder.toString());
            return BindingURLParserState.QUESTION_MARK_CHAR;
        }
    }

    private BindingURLParserState extractQueueName()
    {
        char nextChar = _url[_index];
        StringBuilder builder = new StringBuilder();
        while (nextChar != QUESTION_MARK_CHAR && nextChar != END_OF_URL_MARKER_CHAR)
        {
            builder.append(nextChar);
            nextChar = _url[++_index];
        }
        _bindingURL.setQueueName(builder.toString());

        if(nextChar == QUESTION_MARK_CHAR)
        {
            return BindingURLParserState.QUESTION_MARK_CHAR;
        }
        else
        {
            return BindingURLParserState.BINDING_URL_END;
        }
    }

    private BindingURLParserState extractPropertyName()
    {
        StringBuilder builder = new StringBuilder();
        char next = _url[_index];
        while (next != PROPERTY_EQUALS_CHAR)
        {
            builder.append(next);
            next = _url[++_index];
        }
        _currentPropName = builder.toString();

        if (_currentPropName.trim().equals(""))
        {
            _error = "Property name cannot be empty";
            return BindingURLParserState.ERROR;
        }

        return BindingURLParserState.PROPERTY_EQUALS;
    }

    private BindingURLParserState extractPropertyValue()
    {
        StringBuilder builder = new StringBuilder();
        char next = _url[_index];
        while (next != SINGLE_QUOTE_CHAR)
        {
            builder.append(next);
            next = _url[++_index];
        }
        String propValue = builder.toString();

        if (propValue.trim().equals(""))
        {
            _error = "Property values cannot be empty";
            return BindingURLParserState.ERROR;
        }
        else
        {
            if (_options.containsKey(_currentPropName))
            {
                Object obj = _options.get(_currentPropName);
                if (obj instanceof List)
                {
                    List list = (List)obj;
                    list.add(propValue);
                }
                else // it has to be a string
                {
                    List<String> list = new ArrayList();
                    list.add((String)obj);
                    list.add(propValue);
                    _options.put(_currentPropName, list);
                }
            }
            else
            {
                _options.put(_currentPropName, propValue);
            }


            return BindingURLParserState.END_PROPERTY_VALUE;
        }
    }

    private BindingURLParserState checkEndOfURL()
    {
        char nextChar = _url[_index];
        if ( nextChar ==  END_OF_URL_MARKER_CHAR)
        {
            return BindingURLParserState.BINDING_URL_END;
        }
        else if (nextChar == PROPERTY_SEPARATOR_CHAR || nextChar == ALTERNATIVE_PROPERTY_SEPARATOR_CHAR)
        {
            return BindingURLParserState.PROPERTY_SEPARATOR;
        }
        else
        {
            return BindingURLParserState.ERROR;
        }
    }

    private String markErrorLocation()
    {
        String tmp = String.valueOf(_url);
        // length -1 to remove ENDOF URL marker
        return tmp.substring(0,_index) + "^" + tmp.substring(_index+1> tmp.length()-1?tmp.length()-1:_index+1,tmp.length()-1);
    }

    private void processOptions() throws URISyntaxException
    {
//      check for bindingKey
        if (_options.containsKey(BindingURL.OPTION_BINDING_KEY) && _options.get(BindingURL.OPTION_BINDING_KEY) != null)
        {
            Object obj = _options.get(BindingURL.OPTION_BINDING_KEY);

            if (obj instanceof String)
            {
                String[] bindingKeys = new String[]{(String)obj};
                _bindingURL.setBindingKeys(bindingKeys);
            }
            else // it would be a list
            {
                List list = (List)obj;
                String[] bindingKeys = new String[list.size()];
                int i=0;
                for (Iterator it = list.iterator(); it.hasNext();)
                {
                    bindingKeys[i] = (String)it.next();
                    i++;
                }
                _bindingURL.setBindingKeys(bindingKeys);
            }

        }
        for (String key: _options.keySet())
        {
            // We want to skip the bindingKey list
            if (_options.get(key) instanceof String)
            {
                _bindingURL.setOption(key, (String)_options.get(key));
            }
        }


        // check if both a binding key and a routing key is specified.
        if (_options.containsKey(BindingURL.OPTION_BINDING_KEY) && _options.containsKey(BindingURL.OPTION_ROUTING_KEY))
        {
            throw new URISyntaxException(String.valueOf(_url),"It is illegal to specify both a routingKey and a bindingKey in the same URL",-1);
        }
    }
}
