/*
 * 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.geronimo.javamail.store.nntp;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.mail.Folder;
import javax.mail.MessagingException;

import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
import org.apache.geronimo.mail.util.SessionUtil;

/**
 * The base NNTP implementation of the javax.mail.Folder This is a base class
 * for both the Root NNTP server and each NNTP group folder.
 * 
 * @see javax.mail.Folder
 * 
 * @version $Rev: 437941 $
 */
public class NNTPRootFolder extends NNTPFolder {
    protected static final String NNTP_LISTALL = "mail.nntp.listall";

    /**
     * Construct the NNTPRootFolder.
     * 
     * @param store
     *            The owning Store.
     * @param name
     *            The folder name (by default, this is the server host name).
     * @param fullName
     *            The fullName to use for this server (derived from welcome
     *            string).
     */
    protected NNTPRootFolder(NNTPStore store, String name, String fullName) {
        super(store);

        this.name = name;
        this.fullName = fullName;
    }

    /**
     * List the subfolders. For group folders, this is a meaningless so we throw
     * a MethodNotSupportedException.
     * 
     * @param pattern
     *            The folder pattern string.
     * 
     * @return Never returns.
     * @exception MessagingException
     */
    public synchronized Folder[] list(String pattern) throws MessagingException {
        // the pattern specfied for javamail uses two wild card characters, "%"
        // and "*". The "%" matches
        // and character except hierarchy separators. Since we have a flag
        // hierarchy, "%" and "*" are
        // essentially the same. If we convert the "%" into "*", we can just
        // treat this as a wildmat
        // formatted pattern and pass this on to the server rather than having
        // to read everything and
        // process the strings on the client side.

        pattern = pattern.replace('%', '*');

        // if we're not supposed to list everything, then just filter the list
        // of subscribed groups.
        if (SessionUtil.getBooleanProperty(NNTP_LISTALL, false)) {
            return filterActiveGroups(pattern);
        } else {
            return filterSubscribedGroups(pattern);
        }
    }

    /**
     * Retrieve the list of subscribed folders that match the given pattern
     * string.
     * 
     * @param pattern
     *            The pattern string used for the matching
     * 
     * @return An array of matching folders from the subscribed list.
     */
    public Folder[] listSubscribed(String pattern) throws MessagingException {
        // the pattern specfied for javamail uses two wild card characters, "%"
        // and "*". The "%" matches
        // and character except hierarchy separators. Since we have a flag
        // hierarchy, "%" and "*" are
        // essentially the same. If we convert the "%" into "*", we can just
        // treat this as a wildmat
        // formatted pattern and pass this on to the server rather than having
        // to read everything and
        // process the strings on the client side.

        pattern = pattern.replace('%', '*');

        return filterSubscribedGroups(pattern);
    }

    /**
     * Retrieve the list of matching groups from the NNTP server using the LIST
     * ACTIVE command. The server does the wildcard matching for us.
     * 
     * @param pattern
     *            The pattern string (in wildmat format) used to match.
     * 
     * @return An array of folders for the matching groups.
     */
    protected Folder[] filterActiveGroups(String pattern) throws MessagingException {
        NNTPReply reply = connection.sendCommand("LIST ACTIVE " + pattern, NNTPReply.LIST_FOLLOWS);

        // if the LIST ACTIVE command isn't supported,
        if (reply.getCode() == NNTPReply.COMMAND_NOT_RECOGNIZED) {
            // only way to list all is to retrieve all and filter.
            return filterAllGroups(pattern);
        } else if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
        }

        // get the response back from the server and process each returned group
        // name.
        List groups = reply.getData();

        Folder[] folders = new Folder[groups.size()];
        for (int i = 0; i < groups.size(); i++) {
            folders[i] = getFolder(getGroupName((String) groups.get(i)));
        }
        return folders;
    }

    /**
     * Retrieve a list of all groups from the server and filter on the names.
     * Not recommended for the usenet servers, as there are over 30000 groups to
     * process.
     * 
     * @param pattern
     *            The pattern string used for the selection.
     * 
     * @return The Folders for the matching groups.
     */
    protected Folder[] filterAllGroups(String pattern) throws MessagingException {
        NNTPReply reply = connection.sendCommand("LIST", NNTPReply.LIST_FOLLOWS);

        if (reply.getCode() != NNTPReply.LIST_FOLLOWS) {
            throw new MessagingException("Error retrieving group list from NNTP server: " + reply);
        }

        // get the response back from the server and process each returned group
        // name.
        List groups = reply.getData();

        WildmatMatcher matcher = new WildmatMatcher(pattern);

        List folders = new ArrayList();
        for (int i = 0; i < groups.size(); i++) {
            String name = getGroupName((String) groups.get(i));
            // does this match our pattern? Add to the list
            if (matcher.matches(name)) {
                folders.add(getFolder(name));
            }
        }
        return (Folder[]) folders.toArray(new Folder[0]);
    }

    /**
     * Return the set of groups from the newsrc subscribed groups list that
     * match a given filter.
     * 
     * @param pattern
     *            The selection pattern.
     * 
     * @return The Folders for the matching groups.
     */
    protected Folder[] filterSubscribedGroups(String pattern) throws MessagingException {
        Iterator groups = ((NNTPStore) store).getNewsrcGroups();

        WildmatMatcher matcher = new WildmatMatcher(pattern);

        List folders = new ArrayList();
        while (groups.hasNext()) {
            NNTPNewsrcGroup group = (NNTPNewsrcGroup) groups.next();
            if (group.isSubscribed()) {
                // does this match our pattern? Add to the list
                if (matcher.matches(group.getName())) {
                    folders.add(getFolder(group.getName()));
                }
            }
        }
        return (Folder[]) folders.toArray(new Folder[0]);
    }

    /**
     * Utility method for extracting a name from a group list response.
     * 
     * @param response
     *            The response string.
     * 
     * @return The group name.
     */
    protected String getGroupName(String response) {
        int blank = response.indexOf(' ');
        return response.substring(0, blank).trim();
    }

    /**
     * Return whether this folder can hold just messages or also subfolders.
     * Only the root folder can hold other folders, so it will need to override.
     * 
     * @return Always returns Folder.HOLDS_FOLDERS.
     * @exception MessagingException
     */
    public int getType() throws MessagingException {
        return HOLDS_FOLDERS;
    }

    /**
     * Get a new folder from the root folder. This creates a new folder, which
     * might not actually exist on the server. If the folder doesn't exist, an
     * error will occur on folder open.
     * 
     * @param name
     *            The name of the requested folder.
     * 
     * @return A new folder object for this folder.
     * @exception MessagingException
     */
    public Folder getFolder(String name) throws MessagingException {
        // create a new group folder and return
        return new NNTPGroupFolder(this, (NNTPStore) store, name, ((NNTPStore) store).getNewsrcGroup(name));
    }

    /**
     * Utility class to do Wildmat pattern matching on folder names.
     */
    class WildmatMatcher {
        // middle match sections...because these are separated by wildcards, if
        // they appear in
        // sequence in the string, it is a match.
        List matchSections = new ArrayList();

        // just a "*" match, so everything is true
        boolean matchAny = false;

        // no wildcards, so this must be an exact match.
        String exactMatch = null;

        // a leading section which must be at the beginning
        String firstSection = null;

        // a trailing section which must be at the end of the string.
        String lastSection = null;

        /**
         * Create a wildmat pattern matcher.
         * 
         * @param pattern
         *            The wildmat pattern to apply to string matches.
         */
        public WildmatMatcher(String pattern) {
            int section = 0;

            // handle the easy cases first

            // single wild card?
            if (pattern.equals("*")) {
                matchAny = true;
                return;
            }

            // find the first wild card
            int wildcard = pattern.indexOf('*');

            // no wild card at all?
            if (wildcard == -1) {
                exactMatch = pattern;
                return;
            }

            // pattern not begin with a wildcard? We need to pull off the
            // leading section
            if (!pattern.startsWith("*")) {
                firstSection = pattern.substring(0, wildcard);
                section = wildcard + 1;
                // this could be "yada*", so we could be done.
                if (section >= pattern.length()) {
                    return;
                }
            }

            // now parse off the middle sections, making sure to handle the end
            // condition correctly.
            while (section < pattern.length()) {
                // find the next wildcard position
                wildcard = pattern.indexOf('*', section);
                if (wildcard == -1) {
                    // not found, we're at the end of the pattern. We need to
                    // match on the end.
                    lastSection = pattern.substring(section);
                    return;
                }
                // we could have a null section, which we'll just ignore.
                else if (wildcard == section) {
                    // step over the wild card
                    section++;
                } else {
                    // pluck off the next section
                    matchSections.add(pattern.substring(section, wildcard));
                    // step over the wild card character and check if we've
                    // reached the end.
                    section = wildcard + 1;
                }
            }
        }

        /**
         * Test if a name string matches to parsed wildmat pattern.
         * 
         * @param name
         *            The name to test.
         * 
         * @return true if the string matches the pattern, false otherwise.
         */
        public boolean matches(String name) {

            // handle the easy cases first

            // full wildcard? Always matches
            if (matchAny) {
                return true;
            }

            // required exact matches are easy.
            if (exactMatch != null) {
                return exactMatch.equals(name);
            }

            int span = 0;

            // must match the beginning?
            if (firstSection != null) {
                // if it doesn't start with that, it can't be true.
                if (!name.startsWith(firstSection)) {
                    return false;
                }

                // we do all additional matching activity from here.
                span = firstSection.length();
            }

            // scan for each of the sections along the string
            for (int i = 1; i < matchSections.size(); i++) {
                // if a section is not found, this is false

                String nextMatch = (String) matchSections.get(i);
                int nextLocation = name.indexOf(nextMatch, span);
                if (nextLocation == -1) {
                    return false;
                }
                // step over that one
                span = nextMatch.length() + nextLocation;
            }

            // we've matched everything up to this point, now check to see if
            // need an end match
            if (lastSection != null) {
                // we need to have at least the number of characters of the end
                // string left, else this fails.
                if (name.length() - span < lastSection.length()) {
                    return false;
                }

                // ok, make sure we end with this string
                return name.endsWith(lastSection);
            }

            // no falsies, this must be the truth.
            return true;
        }
    }
}
