/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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 android.net;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 *
 * MailTo URL parser
 *
 * This class parses a mailto scheme URL and then can be queried for
 * the parsed parameters. This implements RFC 2368.
 *
 */
public class MailTo {
    
    static public final String MAILTO_SCHEME = "mailto:";
    
    // All the parsed content is added to the headers.
    private HashMap<String, String> mHeaders;
    
    // Well known headers
    static private final String TO = "to";
    static private final String BODY = "body";
    static private final String CC = "cc";
    static private final String SUBJECT = "subject";

    
    /**
     * Test to see if the given string is a mailto URL
     * @param url string to be tested
     * @return true if the string is a mailto URL
     */
    public static boolean isMailTo(String url) {
        if (url != null && url.startsWith(MAILTO_SCHEME)) {
            return true;
        }
        return false;
    }
    
    /**
     * Parse and decode a mailto scheme string. This parser implements
     * RFC 2368. The returned object can be queried for the parsed parameters.
     * @param url String containing a mailto URL
     * @return MailTo object
     * @exception ParseException if the scheme is not a mailto URL
     */
    public static MailTo parse(String url) throws ParseException {
        if (url == null) {
            throw new NullPointerException();
        }
        if (!isMailTo(url)) {
             throw new ParseException("Not a mailto scheme");
        }
        // Strip the scheme as the Uri parser can't cope with it.
        String noScheme = url.substring(MAILTO_SCHEME.length());
        Uri email = Uri.parse(noScheme);
        MailTo m = new MailTo();
        
        // Parse out the query parameters
        String query = email.getQuery();
        if (query != null ) {
            String[] queries = query.split("&");
            for (String q : queries) {
                String[] nameval = q.split("=");
                if (nameval.length == 0) {
                    continue;
                }
                // insert the headers with the name in lowercase so that
                // we can easily find common headers
                m.mHeaders.put(Uri.decode(nameval[0]).toLowerCase(Locale.ROOT),
                        nameval.length > 1 ? Uri.decode(nameval[1]) : null);
            }
        }
        
        // Address can be specified in both the headers and just after the
        // mailto line. Join the two together.
        String address = email.getPath();
        if (address != null) {
            String addr = m.getTo();
            if (addr != null) {
                address += ", " + addr;
            }
            m.mHeaders.put(TO, address);
        }
        
        return m;
    }
    
    /**
     * Retrieve the To address line from the parsed mailto URL. This could be
     * several email address that are comma-space delimited.
     * If no To line was specified, then null is return
     * @return comma delimited email addresses or null
     */
    public String getTo() {
        return mHeaders.get(TO);
    }
    
    /**
     * Retrieve the CC address line from the parsed mailto URL. This could be
     * several email address that are comma-space delimited.
     * If no CC line was specified, then null is return
     * @return comma delimited email addresses or null
     */
    public String getCc() {
        return mHeaders.get(CC);
    }
    
    /**
     * Retrieve the subject line from the parsed mailto URL.
     * If no subject line was specified, then null is return
     * @return subject or null
     */
    public String getSubject() {
        return mHeaders.get(SUBJECT);
    }
    
    /**
     * Retrieve the body line from the parsed mailto URL.
     * If no body line was specified, then null is return
     * @return body or null
     */
    public String getBody() {
        return mHeaders.get(BODY);
    }
    
    /**
     * Retrieve all the parsed email headers from the mailto URL
     * @return map containing all parsed values
     */
    public Map<String, String> getHeaders() {
        return mHeaders;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(MAILTO_SCHEME);
        sb.append('?');
        for (Map.Entry<String,String> header : mHeaders.entrySet()) {
            sb.append(Uri.encode(header.getKey()));
            sb.append('=');
            sb.append(Uri.encode(header.getValue()));
            sb.append('&');
        }
        return sb.toString();
    }
    
    /**
     * Private constructor. The only way to build a Mailto object is through
     * the parse() method.
     */
    private MailTo() {
        mHeaders = new HashMap<String, String>();
    }
}
