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

import static org.apache.tika.mime.MediaType.OCTET_STREAM;
import static org.apache.tika.mime.MediaType.TEXT_PLAIN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.Before;
import org.junit.Test;

public class MimeTypesTest {

    private MimeTypes types;

    private MediaTypeRegistry registry;

    private MimeType binary;

    private MimeType text;

    private MimeType html;

    @Before
    public void setUp() throws MimeTypeException {
        types = new MimeTypes();
        registry = types.getMediaTypeRegistry();
        binary = types.forName("application/octet-stream");
        text = types.forName("text/plain");
        types.addAlias(text, MediaType.parse("text/x-plain"));
        html = types.forName("text/html");
        types.setSuperType(html, TEXT_PLAIN);
    }

    @Test
    public void testForName() throws MimeTypeException {
        assertEquals(text, types.forName("text/plain"));
        assertEquals(text, types.forName("TEXT/PLAIN"));

        try {
            types.forName("invalid");
            fail("MimeTypeException not thrown on invalid type name");
        } catch (MimeTypeException e) {
            // expected
        }
    }

    @Test
    public void testRegisteredMimes() throws MimeTypeException {
        String dummy = "text/xxxxx";
        assertEquals(text, types.getRegisteredMimeType("text/plain"));
        assertNull(types.getRegisteredMimeType(dummy));
        assertNotNull(types.forName(dummy));
        assertEquals(dummy, types.forName("text/xxxxx").getType().toString());
        assertEquals(dummy, types.getRegisteredMimeType("text/xxxxx").getType().toString());

        try {
            types.forName("invalid");
            fail("MimeTypeException not thrown on invalid type name");
        } catch (MimeTypeException e) {
            // expected
        }
    }

    @Test
    public void testSuperType() throws MimeTypeException {
        assertNull(registry.getSupertype(OCTET_STREAM));
        assertEquals(OCTET_STREAM, registry.getSupertype(TEXT_PLAIN));
        assertEquals(TEXT_PLAIN, registry.getSupertype(html.getType()));
    }

    @Test
    public void testIsDescendantOf() {
        assertFalse(registry.isSpecializationOf(OCTET_STREAM, OCTET_STREAM));
        assertFalse(registry.isSpecializationOf(TEXT_PLAIN, TEXT_PLAIN));
        assertFalse(registry.isSpecializationOf(html.getType(), html.getType()));

        assertTrue(registry.isSpecializationOf(html.getType(), OCTET_STREAM));
        assertFalse(registry.isSpecializationOf(OCTET_STREAM, html.getType()));

        assertTrue(registry.isSpecializationOf(html.getType(), TEXT_PLAIN));
        assertFalse(registry.isSpecializationOf(TEXT_PLAIN, html.getType()));

        assertTrue(registry.isSpecializationOf(TEXT_PLAIN, OCTET_STREAM));
        assertFalse(registry.isSpecializationOf(OCTET_STREAM, TEXT_PLAIN));
    }

    @Test
    public void testCompareTo() {
        assertTrue(binary.compareTo(binary) == 0);
        assertTrue(binary.compareTo(text) != 0);
        assertTrue(binary.compareTo(html) != 0);

        assertTrue(text.compareTo(binary) != 0);
        assertTrue(text.compareTo(text) == 0);
        assertTrue(text.compareTo(html) != 0);

        assertTrue(html.compareTo(binary) != 0);
        assertTrue(html.compareTo(text) != 0);
        assertTrue(html.compareTo(html) == 0);
    }

}
