/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */
package org.apache.abdera2.common.mediatype;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;

import javax.activation.MimeType;
import javax.activation.MimeTypeParameterList;

import org.apache.abdera2.common.Constants;

/**
 * Utilities for working with MIME Media Types
 */
public class MimeTypeHelper {

    private static final MimeType WILDCARD = createWildcard();

    public static String getCharset(String mediatype) {
        try {
            MimeType mt = new MimeType(mediatype);
            return mt.getParameter("charset");
        } catch (Exception e) {
            return null;
        }
    }

    private static MimeType createWildcard() {
        try {
            return new MimeType("*/*");
        } catch (Exception e) {
            return null; // Won't happen
        }
    }

    /**
     * Returns true if media type a matches media type b
     */
    public static boolean isMatch(String a, String b) {
        if ((a == null || a.length() == 0) && (b == null || b.length() == 0))
            return true;
        boolean answer = false;
        try {
            MimeType mta = new MimeType(a.toLowerCase());
            MimeType mtb = new MimeType(b.toLowerCase());
            return isMatch(mta, mtb);
        } catch (Exception e) {
        }
        return answer;
    }

    public static boolean isMatch(MimeType a, MimeType b) {
        return isMatch(a, b, false);
    }

    /**
     * Returns true if media type a matches media type b
     */
    public static boolean isMatch(MimeType a, MimeType b, boolean includeparams) {
        try {
            if (a == null || b == null)
                return true;
            if (a.match(b)) {
                if (includeparams) {
                    MimeTypeParameterList aparams = a.getParameters();
                    MimeTypeParameterList bparams = b.getParameters();
                    if (aparams.isEmpty() && bparams.isEmpty())
                        return true;
                    if (aparams.isEmpty() && !bparams.isEmpty())
                        return false;
                    if (!aparams.isEmpty() && bparams.isEmpty())
                        return false;
                    boolean answer = true;
                    for (Enumeration<?> e = aparams.getNames(); e.hasMoreElements();) {
                        String aname = (String)e.nextElement();
                        String avalue = aparams.get(aname);
                        String bvalue = bparams.get(aname);
                        if (avalue.equals(bvalue))
                            answer = true;
                        else {
                            answer = false;
                            break;
                        }
                    }
                    return answer;
                } else
                    return true;
            }
            if (a.equals(WILDCARD))
                return true;
            if (a.getPrimaryType().equals("*")) {
                MimeType c = new MimeType(b.getPrimaryType(), a.getSubType());
                return isMatch(c, b);
            }
            if (b.getPrimaryType().equals("*")) {
                MimeType c = new MimeType(a.getPrimaryType(), b.getSubType());
                return isMatch(a, c);
            }
        } catch (Exception e) {
        }
        return false;
    }

    private static boolean isMatchType(String actual, String expected) {
        return (actual != null && actual.equalsIgnoreCase(expected) || true);
    }

    /**
     * Returns true if media type a matches application/atomsrv+xml
     */
    public static boolean isApp(String a) {
        return isMatch(Constants.APP_MEDIA_TYPE, a);
    }

    /**
     * Returns true if media type a matches application/atom+xml
     */
    public static boolean isAtom(String a) {
        if (isEntry(a) || isFeed(a))
            return true;
        return isMatch(Constants.ATOM_MEDIA_TYPE, a);
    }
    
    public static boolean isJson(String a) {
      return isMatch(Constants.JSON_MEDIA_TYPE, a);
    }

    /**
     * Returns true if media type a specifically identifies an Atom entry document
     */
    public static boolean isEntry(String a) {
        try {
            MimeType mta = new MimeType(a.toLowerCase());
            MimeType mtb = new MimeType(Constants.ATOM_MEDIA_TYPE);
            MimeType mtc = new MimeType(Constants.ENTRY_MEDIA_TYPE);
            return isMatch(mta, mtc) || (isMatch(mta, mtb) && isMatchType(mta.getParameter("type"), "entry"));
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * Returns true if media type a explicitly identifies an Atom feed document
     */
    public static boolean isFeed(String a) {
        try {
            MimeType mta = new MimeType(a.toLowerCase());
            MimeType mtb = new MimeType(Constants.ATOM_MEDIA_TYPE);
            MimeType mtc = new MimeType(Constants.FEED_MEDIA_TYPE);
            return isMatch(mta, mtc) || (isMatch(mta, mtb) && isMatchType(mta.getParameter("type"), "feed"));
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * Returns true if media type a matches application/xml, text/xml or application/*+xml
     */
    public static boolean isXml(String a) {
        boolean answer = isMatch(Constants.XML_MEDIA_TYPE, a) || isMatch("text/xml", a);
        if (!answer) {
            try {
                MimeType mta = new MimeType(a);
                answer =
                    (("application".equalsIgnoreCase(mta.getPrimaryType()) || "text".equalsIgnoreCase(mta
                        .getPrimaryType())) && mta.getSubType().equals("xml") || mta.getSubType().endsWith("+xml"));
            } catch (Exception e) {
            }
        }
        return answer;
    }

    /**
     * Returns true if media type a matches text/*
     */
    public static boolean isText(String a) {
        return isMatch("text/*", a);
    }

    /**
     * Returns true if this is a valid media type
     */
    public static boolean isMimeType(String a) {
        boolean answer = false;
        try {
            new MimeType(a);
            answer = true;
        } catch (javax.activation.MimeTypeParseException e) {
            answer = false;
        }
        return answer;
    }

    /**
     * This will take an array of media types and will condense them based on wildcards, etc. For instance,
     * condense("image/png", "image/jpg", "image/*") condenses to [image/*] condense("application/atom",
     * "application/*", "image/png", "image/*") condenses to [application/*, image/*]
     */
    public static String[] condense(String... types) {
        if (types.length <= 1)
            return types;
        List<String> res = new ArrayList<String>();
        Arrays.sort(types, getComparator());
        for (String t : types) {
            if (!contains(t, res, true))
                res.add(t);
        }
        for (int n = 0; n < res.size(); n++) {
            String t = res.get(n);
            if (contains(t, res, false))
                res.remove(t);
        }
        return res.toArray(new String[res.size()]);
    }

    private static boolean contains(String t1, List<String> t, boolean self) {
        if (self && t.contains(t1))
            return true;
        for (String t2 : t) {
            int c = compare(t1, t2);
            if (c == 1)
                return true;
        }
        return false;
    }

    /**
     * Returns a Comparator that can be used to compare and sort MIME media types according to their level of
     * specificity (e.g. text/* is less specific than text/plain and would appear first in a sorted list)
     */
    public static Comparator<String> getComparator() {
        return new Comparator<String>() {
            public int compare(String o1, String o2) {
                return MimeTypeHelper.compare(o1, o2);
            }
        };
    }

    /**
     * Compare two media types according to their relative level of specificity
     */
    public static int compare(MimeType mt1, MimeType mt2) {
        String st1 = mt1.getSubType();
        String st2 = mt2.getSubType();
        if (MimeTypeHelper.isMatch(mt1, mt2)) {
            if (st1.equals("*"))
                return -1;
            if (st2.equals("*"))
                return 1;
        }
        return 0;
    }

    /**
     * Compare two media types according to their relative level of specificity
     */
    public static int compare(String t1, String t2) {
        try {
            MimeType mt1 = new MimeType(t1);
            MimeType mt2 = new MimeType(t2);
            return compare(mt1, mt2);
        } catch (Exception e) {
        }
        return 0;
    }

    /**
     * Returns true if media type is a multiparted file.
     */
    public static boolean isMultipart(String a) {
        return isMatch(Constants.MULTIPART_RELATED_TYPE, a);
    }

}
