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

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.CopyOnWriteArraySet;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.firewall.Subnet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An implementation of the <code>SessionFilter</code> interface, to filter
 * sessions based on the remote IP address.
 * 
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 * 
 */

public class RemoteIpFilter extends CopyOnWriteArraySet<Subnet> implements
        SessionFilter {

    /**
     * Logger
     */
    Logger LOGGER = LoggerFactory.getLogger(RemoteIpFilter.class);

    /**
     * Serial version UID
     */
    private static final long serialVersionUID = 4887092372700628783L;

    /**
     * filter type
     */
    private IpFilterType type = null;

    /**
     * Creates a new instance of <code>RemoteIpFilter</code>.
     * 
     * @param type
     *            the filter type
     */
    public RemoteIpFilter(IpFilterType type) {
        this(type, new HashSet<Subnet>(0));
    }

    /**
     * Creates a new instance of <code>RemoteIpFilter</code>.
     * 
     * @param type
     *            the filter type
     * @param collection
     *            a collection of <code>Subnet</code>s to filter out/in.
     */
    public RemoteIpFilter(IpFilterType type,
            Collection<? extends Subnet> collection) {
        super(collection);
        this.type = type;
    }

    /**
     * Creates a new instance of <code>RemoteIpFilter</code>.
     * 
     * @param type
     *            the filter type
     * @param addresses
     *            a comma, space, tab, CR, LF separated list of IP
     *            addresses/CIDRs.
     * @throws UnknownHostException
     *             propagated
     * @throws NumberFormatException
     *             propagated
     */
    public RemoteIpFilter(IpFilterType type, String addresses)
            throws NumberFormatException, UnknownHostException {
        super();
        this.type = type;
        if (addresses != null) {
            String[] tokens = addresses.split("[\\s,]+");
            for (String token : tokens) {
                if (token.trim().length() > 0) {
                    add(token);
                }
            }
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(
                    "Created DefaultIpFilter of type {} with the subnets {}",
                    type, this);
        }
    }

    /**
     * Returns the type of this filter.
     * 
     * @return the type of this filter.
     */
    public IpFilterType getType() {
        return type;
    }

    /**
     * Sets the type of this filter.
     * 
     * @param type
     *            the type of this filter.
     */
    public void setType(IpFilterType type) {
        this.type = type;
    }

    /**
     * Adds the given string representation of InetAddress or CIDR notation to
     * this filter.
     * 
     * @param str
     *            the string representation of InetAddress or CIDR notation
     * @return if the given element was added or not. <code>true</code>, if the
     *         given element was added to the filter; <code>false</code>, if the
     *         element already exists in the filter.
     * @throws NumberFormatException
     *             propagated
     * @throws UnknownHostException
     *             propagated
     */
    public boolean add(String str) throws NumberFormatException,
            UnknownHostException {
        // This is required so we do not block loopback address if some one adds
        // a string with blanks as the InetAddress class assumes loopback
        // address on a blank string.
        if (str.trim().length() < 1) {
            throw new IllegalArgumentException("Invalid IP Address or Subnet: "
                    + str);
        }
        String[] tokens = str.split("/");
        if (tokens.length == 2) {
            return add(new Subnet(InetAddress.getByName(tokens[0]), Integer
                    .parseInt(tokens[1])));
        } else {
            return add(new Subnet(InetAddress.getByName(tokens[0]), 32));
        }
    }

    public boolean accept(IoSession session) {
        InetAddress address = ((InetSocketAddress) session.getRemoteAddress())
                .getAddress();
        switch (type) {
        case ALLOW:
            for (Subnet subnet : this) {
                if (subnet.inSubnet(address)) {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER
                                .debug(
                                        "Allowing connection from {} because it matches with the whitelist subnet {}",
                                        address, subnet);
                    }
                    return true;
                }
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER
                        .debug(
                                "Denying connection from {} because it does not match any of the whitelist subnets",
                                address);
            }
            return false;
        case DENY:
            if (isEmpty()) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER
                            .debug(
                                    "Allowing connection from {} because blacklist is empty",
                                    address);
                }
                return true;
            }
            for (Subnet subnet : this) {
                if (subnet.inSubnet(address)) {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER
                                .debug(
                                        "Denying connection from {} because it matches with the blacklist subnet {}",
                                        address, subnet);
                    }
                    return false;
                }
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER
                        .debug(
                                "Allowing connection from {} because it does not match any of the blacklist subnets",
                                address);
            }
            return true;
        default:
            throw new IllegalStateException("Unknown or unimplemented filter type: "
                    + type);
        }
    }
}
