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

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @version $Rev$ $Date$
 */
public class MailcapCommandMap extends CommandMap {
    private final Map mimeTypes = new HashMap();
    private final Map preferredCommands = new HashMap();
    private final Map allCommands = new HashMap();
    // the unparsed commands from the mailcap file.
    private final Map nativeCommands = new HashMap();
    // commands identified as fallbacks...these are used last, and also used as wildcards.
    private final Map fallbackCommands = new HashMap();
    private URL url;

    public MailcapCommandMap() {
        ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
        // process /META-INF/mailcap.default
        try {
            InputStream is = MailcapCommandMap.class.getResourceAsStream("/META-INF/mailcap.default");
            if (is != null) {
                try {
                    parseMailcap(is);
                } finally {
                    is.close();
                }
            }
        } catch (IOException e) {
            // ignore
        }

        // process /META-INF/mailcap resources
        try {
            Enumeration e = contextLoader.getResources("META-INF/mailcap");
            while (e.hasMoreElements()) {
                url = ((URL) e.nextElement());
                try {
                    InputStream is = url.openStream();
                    try {
                        parseMailcap(is);
                    } finally {
                        is.close();
                    }
                } catch (IOException e1) {
                    continue;
                }
            }
        } catch (SecurityException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }

        // process ${java.home}/lib/mailcap
        try {
            File file = new File(System.getProperty("java.home"), "lib/mailcap");
            InputStream is = new FileInputStream(file);
            try {
                parseMailcap(is);
            } finally {
                is.close();
            }
        } catch (SecurityException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }

        // process ${user.home}/lib/mailcap
        try {
            File file = new File(System.getProperty("user.home"), ".mailcap");
            InputStream is = new FileInputStream(file);
            try {
                parseMailcap(is);
            } finally {
                is.close();
            }
        } catch (SecurityException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }
    }

    public MailcapCommandMap(String fileName) throws IOException {
        this();
        FileReader reader = new FileReader(fileName);
        try {
            parseMailcap(reader);
        } finally {
            reader.close();
        }
    }

    public MailcapCommandMap(InputStream is) {
        this();
        parseMailcap(is);
    }

    private void parseMailcap(InputStream is) {
        try {
            parseMailcap(new InputStreamReader(is));
        } catch (IOException e) {
            // spec API means all we can do is swallow this
        }
    }

    void parseMailcap(Reader reader) throws IOException {
        BufferedReader br = new BufferedReader(reader);
        String line;
        while ((line = br.readLine()) != null) {
            addMailcap(line);
        }
    }

    public synchronized void addMailcap(String mail_cap) {
        int index = 0;
        // skip leading whitespace
        index = skipSpace(mail_cap, index);
        if (index == mail_cap.length() || mail_cap.charAt(index) == '#') {
            return;
        }

        // get primary type
        int start = index;
        index = getToken(mail_cap, index);
        if (start == index) {
            return;
        }
        String mimeType = mail_cap.substring(start, index);

        // skip any spaces after the primary type
        index = skipSpace(mail_cap, index);
        if (index == mail_cap.length() || mail_cap.charAt(index) == '#') {
            return;
        }

        // get sub-type
        if (mail_cap.charAt(index) == '/') {
            index = skipSpace(mail_cap, ++index);
            start = index;
            index = getToken(mail_cap, index);
            mimeType = mimeType + '/' + mail_cap.substring(start, index);
        } else {

            mimeType = mimeType + "/*";
        }

        // we record all mappings using the lowercase version.
        mimeType = mimeType.toLowerCase();

        // skip spaces after mime type
        index = skipSpace(mail_cap, index);

        // expect a ';' to terminate field 1
        if (index == mail_cap.length() || mail_cap.charAt(index) != ';') {
            return;
        }
        // ok, we've parsed the mime text field, now parse the view field.  If there's something
        // there, then we add this to the native text.
        index = skipSpace(mail_cap, index + 1);
        // if the next encountered text is not a ";", then we have a view.  This gets added to the
        // native list.
        if (index == mail_cap.length() || mail_cap.charAt(index) != ';') {
            ArrayList nativeCommandList = (ArrayList)nativeCommands.get(mimeType);

            // if this is the first for this mimetype, create a holder
            if (nativeCommandList == null) {
                nativeCommandList = new ArrayList();
                nativeCommands.put(mimeType, nativeCommandList);
            }

            // now add this as an entry in the list.
            nativeCommandList.add(mail_cap);
            // now skip forward to the next field marker, if any
            index = getMText(mail_cap, index);
        }

        // we don't know which list this will be added to until we finish parsing, as there
        // can be an x-java-fallback-entry parameter that moves this to the fallback list.
        List commandList = new ArrayList();
        // but by default, this is not a fallback.
        boolean fallback = false;

        int fieldNumber = 0;

        // parse fields
        while (index < mail_cap.length() && mail_cap.charAt(index) == ';') {
            index = skipSpace(mail_cap, index + 1);
            start = index;
            index = getToken(mail_cap, index);
            String fieldName = mail_cap.substring(start, index).toLowerCase();
            index = skipSpace(mail_cap, index);
            if (index < mail_cap.length() && mail_cap.charAt(index) == '=') {
                index = skipSpace(mail_cap, index + 1);
                start = index;
                index = getMText(mail_cap, index);
                String value = mail_cap.substring(start, index);
                index = skipSpace(mail_cap, index);
                if (fieldName.startsWith("x-java-") && fieldName.length() > 7) {
                    String command = fieldName.substring(7);
                    value = value.trim();
                    if (command.equals("fallback-entry")) {
                        if (value.equals("true")) {
                            fallback = true;
                        }
                    }
                    else {
                        // create a CommandInfo item and add it the accumulator
                        CommandInfo info = new CommandInfo(command, value);
                        commandList.add(info);
                    }
                }
            }
        }
        addCommands(mimeType, commandList, fallback);
    }

    /**
     * Add a parsed list of commands to the appropriate command list.
     *
     * @param mimeType The mimeType name this is added under.
     * @param commands A List containing the command information.
     * @param fallback The target list identifier.
     */
    protected void addCommands(String mimeType, List commands, boolean fallback) {
        // add this to the mimeType set
        mimeTypes.put(mimeType, mimeType);
        // the target list changes based on the type of entry.
        Map target = fallback ? fallbackCommands : preferredCommands;

        // now process
        for (Iterator i = commands.iterator(); i.hasNext();) {
            CommandInfo info = (CommandInfo)i.next();
            addCommand(target, mimeType, info);
            // if this is not a fallback position, then this to the allcommands list.
            if (!fallback) {
                List cmdList = (List) allCommands.get(mimeType);
                if (cmdList == null) {
                    cmdList = new ArrayList();
                    allCommands.put(mimeType, cmdList);
                }
                addUnique(cmdList, info);
            }
        }
    }

    private void addUnique(List commands, CommandInfo newCommand) {
        for (Iterator i = commands.iterator(); i.hasNext();) {
            CommandInfo info = (CommandInfo)i.next();
            if (info.getCommandName().equals(newCommand.getCommandName())
                    && info.getCommandClass().equals(newCommand.getCommandClass())) {
                return;
            }
        }
        commands.add(newCommand);
    }

    /**
     * Add a command to a target command list (preferred or fallback).
     *
     * @param commandList
     *                 The target command list.
     * @param mimeType The MIME type the command is associated with.
     * @param command  The command information.
     */
    protected void addCommand(Map commandList, String mimeType, CommandInfo command) {

        Map commands = (Map) commandList.get(mimeType);
        if (commands == null) {
            commands = new HashMap();
            commandList.put(mimeType, commands);
        }
        commands.put(command.getCommandName(), command);
    }


    private int skipSpace(String s, int index) {
        while (index < s.length() && Character.isWhitespace(s.charAt(index))) {
            index++;
        }
        return index;
    }

    private int getToken(String s, int index) {
        while (index < s.length() && s.charAt(index) != '#' && !MimeType.isSpecial(s.charAt(index))) {
            index++;
        }
        return index;
    }

    private int getMText(String s, int index) {
        while (index < s.length()) {
            char c = s.charAt(index);
            if (c == '#' || c == ';' || Character.isISOControl(c)) {
                return index;
            }
            if (c == '\\') {
                index++;
                if (index == s.length()) {
                    return index;
                }
            }
            index++;
        }
        return index;
    }

    public synchronized CommandInfo[] getPreferredCommands(String mimeType) {
        // get the mimetype as a lowercase version.
        mimeType = mimeType.toLowerCase();

        Map commands = (Map) preferredCommands.get(mimeType);
        if (commands == null) {
            commands = (Map) preferredCommands.get(getWildcardMimeType(mimeType));
        }

        Map fallbackCommands = getFallbackCommands(mimeType);

        // if we have fall backs, then we need to merge this stuff.
        if (fallbackCommands != null) {
            // if there's no command list, we can just use this as the master list.
            if (commands == null) {
                commands = fallbackCommands;
            }
            else {
                // merge the two lists.  The ones in the commands list will take precedence.
                commands = mergeCommandMaps(commands, fallbackCommands);
            }
        }

        // now convert this into an array result.
        if (commands == null) {
            return new CommandInfo[0];
        }
        return (CommandInfo[]) commands.values().toArray(new CommandInfo[commands.size()]);
    }

    private Map getFallbackCommands(String mimeType) {
        Map commands = (Map) fallbackCommands.get(mimeType);

        // now we also need to search this as if it was a wildcard.  If we get a wildcard hit,
        // we have to merge the two lists.
        Map wildcardCommands = (Map)fallbackCommands.get(getWildcardMimeType(mimeType));
        // no wildcard version
        if (wildcardCommands == null) {
            return commands;
        }
        // we need to merge these.
        return mergeCommandMaps(commands, wildcardCommands);
    }


    private Map mergeCommandMaps(Map main, Map fallback) {
        // create a cloned copy of the second map.  We're going to use a PutAll operation to
        // overwrite any duplicates.
        Map result = new HashMap(fallback);
        result.putAll(main);

        return result;
    }

    public synchronized CommandInfo[] getAllCommands(String mimeType) {
        mimeType = mimeType.toLowerCase();
        List exactCommands = (List) allCommands.get(mimeType);
        if (exactCommands == null) {
            exactCommands = Collections.EMPTY_LIST;
        }
        List wildCommands = (List) allCommands.get(getWildcardMimeType(mimeType));
        if (wildCommands == null) {
            wildCommands = Collections.EMPTY_LIST;
        }

        Map fallbackCommands = getFallbackCommands(mimeType);
        if (fallbackCommands == null) {
            fallbackCommands = Collections.EMPTY_MAP;
        }


        CommandInfo[] result = new CommandInfo[exactCommands.size() + wildCommands.size() + fallbackCommands.size()];
        int j = 0;
        for (int i = 0; i < exactCommands.size(); i++) {
            result[j++] = (CommandInfo) exactCommands.get(i);
        }
        for (int i = 0; i < wildCommands.size(); i++) {
            result[j++] = (CommandInfo) wildCommands.get(i);
        }

        for (Iterator i = fallbackCommands.keySet().iterator(); i.hasNext();) {
            result[j++] = (CommandInfo) fallbackCommands.get((String)i.next());
        }
        return result;
    }

    public synchronized CommandInfo getCommand(String mimeType, String cmdName) {
        mimeType = mimeType.toLowerCase();
        // strip any parameters from the supplied mimeType
        int i = mimeType.indexOf(';');
        if (i != -1) {
            mimeType = mimeType.substring(0, i).trim();
        }
        cmdName = cmdName.toLowerCase();

        // search for an exact match
        Map commands = (Map) preferredCommands.get(mimeType);
        if (commands == null || commands.get(cmdName) == null) {
            // then a wild card match
            commands = (Map) preferredCommands.get(getWildcardMimeType(mimeType));
            if (commands == null || commands.get(cmdName) == null) {
                // then fallback searches, both standard and wild card.
                commands = (Map) fallbackCommands.get(mimeType);
                if (commands == null || commands.get(cmdName) == null) {
                    commands = (Map) fallbackCommands.get(getWildcardMimeType(mimeType));
                }
                if (commands == null) {
                    return null;
                }
            }
        }
        return (CommandInfo) commands.get(cmdName);
    }

    private String getWildcardMimeType(String mimeType) {
        int i = mimeType.indexOf('/');
        if (i == -1) {
            return mimeType + "/*";
        } else {
            return mimeType.substring(0, i + 1) + "*";
        }
    }

    public synchronized DataContentHandler createDataContentHandler(String mimeType) {

        CommandInfo info = getCommand(mimeType, "content-handler");
        if (info == null) {
            return null;
        }

        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        if (cl == null) {
            cl = getClass().getClassLoader();
        }
        try {
            return (DataContentHandler) cl.loadClass(info.getCommandClass()).newInstance();
        } catch (ClassNotFoundException e) {
            return null;
        } catch (IllegalAccessException e) {
            return null;
        } catch (InstantiationException e) {
            return null;
        }
    }

    /**
     * Get all MIME types known to this command map.
     *
     * @return A String array of the MIME type names.
     */
    public synchronized String[] getMimeTypes() {
        ArrayList types = new ArrayList(mimeTypes.values());
        return (String[])types.toArray(new String[types.size()]);
    }

    /**
     * Return the list of raw command strings parsed
     * from the mailcap files for a given mimeType.
     *
     * @param mimeType The target mime type
     *
     * @return A String array of the raw command strings.  Returns
     *         an empty array if the mimetype is not currently known.
     */
    public synchronized String[] getNativeCommands(String mimeType) {
        ArrayList commands = (ArrayList)nativeCommands.get(mimeType.toLowerCase());
        if (commands == null) {
            return new String[0];
        }
        return (String[])commands.toArray(new String[commands.size()]);
    }
}
