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

import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.filter.SelectorParsingException;
import org.apache.qpid.filter.selector.ParseException;
import org.apache.qpid.filter.selector.TokenMgrError;
import org.apache.qpid.server.consumer.ConsumerImpl;
import org.apache.qpid.server.message.MessageSource;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.plugin.PluggableService;

public class FilterSupport
{
    private static final Map<String, WeakReference<JMSSelectorFilter>> _selectorCache =
            Collections.synchronizedMap(new WeakHashMap<String, WeakReference<JMSSelectorFilter>>());

    static MessageFilter createJMSSelectorFilter(Map<String, Object> args) throws AMQInvalidArgumentException
    {
        final String selectorString = (String) args.get(AMQPFilterTypes.JMS_SELECTOR.toString());
        return getMessageFilter(selectorString);
    }


    private static MessageFilter getMessageFilter(String selectorString) throws AMQInvalidArgumentException
    {
        WeakReference<JMSSelectorFilter> selectorRef = _selectorCache.get(selectorString);
        JMSSelectorFilter selector = null;

        if(selectorRef == null || (selector = selectorRef.get())==null)
        {
            try
            {
                selector = new JMSSelectorFilter(selectorString);
            }
            catch (ParseException | SelectorParsingException | TokenMgrError e)
            {
                throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selectorString + "\"", e);
            }
            _selectorCache.put(selectorString, new WeakReference<JMSSelectorFilter>(selector));
        }
        return selector;
    }

    public static boolean argumentsContainFilter(final Map<String, Object> args)
    {
        return argumentsContainNoLocal(args) || argumentsContainJMSSelector(args);
    }


    public static void removeFilters(final Map<String, Object> args)
    {
        args.remove(AMQPFilterTypes.JMS_SELECTOR.toString());
        args.remove(AMQPFilterTypes.NO_LOCAL.toString());
    }



    static boolean argumentsContainNoLocal(final Map<String, Object> args)
    {
        return args != null
                && args.containsKey(AMQPFilterTypes.NO_LOCAL.toString())
                && Boolean.TRUE.equals(args.get(AMQPFilterTypes.NO_LOCAL.toString()));
    }

    static boolean argumentsContainJMSSelector(final Map<String,Object> args)
    {
        return args != null && (args.get(AMQPFilterTypes.JMS_SELECTOR.toString()) instanceof String)
                       && ((String)args.get(AMQPFilterTypes.JMS_SELECTOR.toString())).trim().length() != 0;
    }

    public static FilterManager createMessageFilter(final Map<String,Object> args, Queue<?> queue) throws AMQInvalidArgumentException
    {
        FilterManager filterManager = null;
        if(argumentsContainNoLocal(args))
        {
            filterManager = new FilterManager();
            filterManager.add(AMQPFilterTypes.NO_LOCAL.toString(), new NoLocalFilter(queue));
        }

        if(argumentsContainJMSSelector(args))
        {
            if(filterManager == null)
            {
                filterManager = new FilterManager();
            }
            filterManager.add(AMQPFilterTypes.JMS_SELECTOR.toString(),createJMSSelectorFilter(args));
        }
        return filterManager;

    }

    @PluggableService
    public static final class NoLocalFilter implements MessageFilter
    {
        private final MessageSource _queue;

        private NoLocalFilter(MessageSource queue)
        {
            _queue = queue;
        }

        @Override
        public String getName()
        {
            return AMQPFilterTypes.NO_LOCAL.toString();
        }

        public boolean matches(Filterable message)
        {

            final Collection<? extends ConsumerImpl> consumers = _queue.getConsumers();
            for(ConsumerImpl c : consumers)
            {
                if(c.getSessionModel().getConnectionReference() == message.getConnectionReference())
                {
                    return false;
                }
            }
            return !consumers.isEmpty();
        }

        @Override
        public boolean startAtTail()
        {
            return false;
        }

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

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

            NoLocalFilter that = (NoLocalFilter) o;

            return _queue == null ? that._queue == null : _queue.equals(that._queue);
        }

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

        @Override
        public String toString()
        {
            return "NoLocalFilter[]";
        }
    }

}
