/*
 * 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.cassandra.distributed.shared;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.cassandra.distributed.api.IMessage;
import org.apache.cassandra.distributed.api.IMessageFilters;

public class MessageFilters implements IMessageFilters
{
    private final List<Filter> inboundFilters = new CopyOnWriteArrayList<>();
    private final List<Filter> outboundFilters = new CopyOnWriteArrayList<>();

    public boolean permitInbound(int from, int to, IMessage msg)
    {
        return permit(inboundFilters, from, to, msg);
    }

    public boolean permitOutbound(int from, int to, IMessage msg)
    {
        return permit(outboundFilters, from, to, msg);
    }

    private static boolean permit(List<Filter> filters, int from, int to, IMessage msg)
    {
        for (Filter filter : filters)
        {
            if (filter.matches(from, to, msg))
                return false;
        }
        return true;
    }

    public static class Filter implements IMessageFilters.Filter
    {
        final int[] from;
        final int[] to;
        final int[] verbs;
        final Matcher matcher;
        final List<Filter> parent;

        Filter(int[] from, int[] to, int[] verbs, Matcher matcher, List<Filter> parent)
        {
            if (from != null)
            {
                from = from.clone();
                Arrays.sort(from);
            }
            if (to != null)
            {
                to = to.clone();
                Arrays.sort(to);
            }
            if (verbs != null)
            {
                verbs = verbs.clone();
                Arrays.sort(verbs);
            }
            this.from = from;
            this.to = to;
            this.verbs = verbs;
            this.matcher = matcher;
            this.parent = Objects.requireNonNull(parent, "parent");
        }

        public int hashCode()
        {
            return (from == null ? 0 : Arrays.hashCode(from))
                   + (to == null ? 0 : Arrays.hashCode(to))
                   + (verbs == null ? 0 : Arrays.hashCode(verbs)
                                          + parent.hashCode());
        }

        public boolean equals(Object that)
        {
            return that instanceof Filter && equals((Filter) that);
        }

        public boolean equals(Filter that)
        {
            return Arrays.equals(from, that.from)
                   && Arrays.equals(to, that.to)
                   && Arrays.equals(verbs, that.verbs)
                   && parent.equals(that.parent);
        }

        public Filter off()
        {
            parent.remove(this);
            return this;
        }

        public Filter on()
        {
            parent.add(this);
            return this;
        }

        public boolean matches(int from, int to, IMessage msg)
        {
            return (this.from == null || Arrays.binarySearch(this.from, from) >= 0)
                   && (this.to == null || Arrays.binarySearch(this.to, to) >= 0)
                   && (this.verbs == null || Arrays.binarySearch(this.verbs, msg.verb()) >= 0)
                   && (this.matcher == null || this.matcher.matches(from, to, msg));
        }
    }

    public class Builder implements IMessageFilters.Builder
    {
        int[] from;
        int[] to;
        int[] verbs;
        Matcher matcher;
        boolean inbound;

        private Builder(boolean inbound)
        {
            this.inbound = inbound;
        }

        public Builder from(int... nums)
        {
            from = nums;
            return this;
        }

        public Builder to(int... nums)
        {
            to = nums;
            return this;
        }

        public IMessageFilters.Builder verbs(int... verbs)
        {
            this.verbs = verbs;
            return this;
        }

        public IMessageFilters.Builder allVerbs()
        {
            this.verbs = null;
            return this;
        }

        public IMessageFilters.Builder inbound(boolean inbound)
        {
            this.inbound = inbound;
            return this;
        }

        public IMessageFilters.Builder messagesMatching(Matcher matcher)
        {
            this.matcher = matcher;
            return this;
        }

        public IMessageFilters.Filter drop()
        {
            return new Filter(from, to, verbs, matcher, inbound ? inboundFilters : outboundFilters).on();
        }
    }

    public IMessageFilters.Builder inbound(boolean inbound)
    {
        return new Builder(inbound);
    }

    @Override
    public void reset()
    {
        inboundFilters.clear();
        outboundFilters.clear();
    }
}
