/*
 * 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.axiom.mime;

import java.text.ParseException;

/**
 * Represents a media type as defined by <a href="http://tools.ietf.org/html/rfc2045">RFC 2045</a>
 * and <a href="http://tools.ietf.org/html/rfc2046">RFC 2046</a>. It specifies a primary type (e.g.
 * {@code text}) and a subtype (e.g. {@code xml}). Note that in RFC 2045, "media type" refers to
 * what is called "primary type" here, while this class uses "media type" to refer to the
 * combination of primary and subtype.
 * <p>
 * This class is immutable. It overrides {@link Object#equals(Object)} and {@link Object#hashCode()}
 * to allow comparing media types as described by RFC 2045, i.e. in a case insensitive way.
 */
public final class MediaType {
    /**
     * The media type for {@code text/xml}.
     */
    public static final MediaType TEXT_XML = new MediaType("text", "xml");
    
    /**
     * The media type for {@code application/xml}.
     */
    public static final MediaType APPLICATION_XML = new MediaType("application", "xml");
    
    /**
     * The media type for {@code application/soap+xml}.
     */
    public static final MediaType APPLICATION_SOAP_XML = new MediaType("application", "soap+xml");
    
    /**
     * The media type for {@code application/xop+xml}.
     */
    public static final MediaType APPLICATION_XOP_XML = new MediaType("application", "xop+xml");
    
    /**
     * The media type for {@code multipart/related}.
     */
    public static final MediaType MULTIPART_RELATED = new MediaType("multipart", "related");
    
    /**
     * The media type for {@code application/octet-stream}.
     */
    public static final MediaType APPLICATION_OCTET_STREAM = new MediaType("application", "octet-stream");
    
    /**
     * The media type for {@code text/plain}.
     */
    public static final MediaType TEXT_PLAIN = new MediaType("text", "plain");
    
    private final String primaryType;
    private final String subType;
    
    /**
     * Constructor.
     * 
     * @param primaryType
     *            the primary type
     * @param subType
     *            the subtype
     */
    public MediaType(String primaryType, String subType) {
        this.primaryType = primaryType;
        this.subType = subType;
    }

    /**
     * Constructor that parses a media type.
     * 
     * @param type
     *            the media type to parse
     * @throws ParseException
     *             if the value is invalid and could not be parsed
     */
    public MediaType(String type) throws ParseException {
        ContentTypeTokenizer tokenizer = new ContentTypeTokenizer(type);
        primaryType = tokenizer.requireToken();
        tokenizer.require('/');
        subType = tokenizer.requireToken();
        tokenizer.requireEndOfString();
    }

    /**
     * Get the primary type.
     * 
     * @return the primary type
     */
    public String getPrimaryType() {
        return primaryType;
    }

    /**
     * Get the subtype.
     * 
     * @return the subtype
     */
    public String getSubType() {
        return subType;
    }

    /**
     * Check if this media type has the given primary type.
     * 
     * @param type
     *            the primary type to check against
     * @return whether the primary type matches
     */
    public boolean hasPrimaryType(String type) {
        return primaryType.equalsIgnoreCase(type);
    }

    /**
     * Check if this media type has the given sub type.
     * 
     * @param type
     *            the sub type to check against
     * @return whether the sub type matches
     */
    public boolean hasSubType(String type) {
        return subType.equalsIgnoreCase(type);
    }

    /**
     * Check if this media type describes XML content as defined in
     * <a href="http://tools.ietf.org/html/rfc7303">RFC 7303</a>.
     * 
     * @return whether the content expected for this media type is XML
     */
    public boolean isXML() {
        return equals(TEXT_XML)
                || hasPrimaryType("application") && (
                        hasSubType("xml")
                        || subType.length() > 4 && subType.substring(subType.length() - 4).equalsIgnoreCase("+xml"));
    }

    @Override
    public int hashCode() {
        int hash = 0;
        for (int i=0, l=primaryType.length(); i<l; i++) {
            hash = 31*hash + Character.toLowerCase(primaryType.charAt(i));
        }
        hash *= 31;
        for (int i=0, l=subType.length(); i<l; i++) {
            hash = 31*hash + Character.toLowerCase(subType.charAt(i));
        }
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MediaType) {
            MediaType other = (MediaType)obj;
            return primaryType.equalsIgnoreCase(other.primaryType) && subType.equalsIgnoreCase(other.subType);
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return primaryType + "/" + subType;
    }
}
