// ***************************************************************************************************************************
// * 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.juneau.https;

import java.util.*;

import org.apache.juneau.http.*;
import org.apache.juneau.json.*;
import org.apache.juneau.testutils.*;
import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;

/**
 * Verifies that the Content-Type class handles matching correctly.
 */
@RunWith(Parameterized.class)
public class ContentTypeTest {
	@Parameterized.Parameters
	public static Collection<Object[]> getParameters() {
		return Arrays.asList(new Object[][] {

			// label, accept-header, media-types, expected-index

			// Simple matches
			{ "SimpleMatch-1", "text/json", "['text/json']", 0 },
			{ "SimpleMatch-2", "text/json", "['text/json','text/foo']", 0 },
			{ "SimpleMatch-3", "text/json", "['text/foo','text/json']", 1 },

			// Simple no-matches
			{ "SimpleNoMatch-1", "text/jsonx", "['text/json']", -1 },
			{ "SimpleNoMatch-2", "text/jso", "['text/json']", -1 },
			{ "SimpleNoMatch-3", "text/json", "['application/json']", -1 },
			{ "SimpleNoMatch-4", "text/json", "[]", -1 },

			{ "XmlAndRdf-1", "text/xml+rdf", "['text/xml','text/xml+rdf']", 1 },
			{ "XmlAndRdf-2", "text/xml+rdf", "['text/xml+rdf','text/xml']", 0 },

			// Fuzzy matches
			{ "Fuzzy-1", "text/1+2", "['text/1+2']", 0 },
			// Order of subtype parts shouldn't matter.
			{ "Fuzzy-2", "text/2+1", "['text/1+2']", 0 },
			// Should match if Accept has 'extra' subtypes.
			// For example, "Accept: text/json+activity" should match against the "text/json" serializer.
			{ "Fuzzy-3", "text/1+2", "['text/1']", 0 },
			// Shouldn't match because the accept media type must be at least a subset of the real media type
			// For example, "Accept: text/json" should not match against the "text/json+lax" serializer.
			{ "Fuzzy-4", "text/1", "['text/1+2']", -1 },
			{ "Fuzzy-5", "text/1+2", "['text/1','text/1+3']", 0 },
			// "text/1+2" should be a better match than just "text/1"
			{ "Fuzzy-6", "text/1+2", "['text/1','text/1+2','text/1+2+3']", 1 },
			// Same as last, but mix up the order a bit.
			{ "Fuzzy-7", "text/1+2", "['text/1+2+3','text/1','text/1+2']", 2 },
			// Same as last, but mix up the order of the subtypes as well.
			{ "Fuzzy-8", "text/1+2", "['text/3+2+1','text/1','text/2+1']", 2 },
			{ "Fuzzy-9", "text/1+2+3+4", "['text/1+2','text/1+2+3']", 1 },
			{ "Fuzzy-10", "text/1+2+3+4", "['text/1+2+3','text/1+2']", 0 },
			{ "Fuzzy-11", "text/4+2+3+1", "['text/1+2+3','text/1+2']", 0 },
			{ "Fuzzy-12", "text/4+2+3+1", "['text/1+2','text/1+2+3']", 1 },
		});
	}

	private String label, contentType, mediaTypes;
	private int expected;

	public ContentTypeTest(String label, String contentType, String mediaTypes, int expected) {
		this.label = label;
		this.contentType = contentType;
		this.mediaTypes = mediaTypes;
		this.expected = expected;
	}

	@Test
	public void test() throws Exception {
		ContentType ct = ContentType.forString(this.contentType);
		MediaType[] mt = JsonParser.DEFAULT.parse(mediaTypes, MediaType[].class);
		int r = ct.findMatch(mt);
		TestUtils.assertEquals(expected, r, "{0} failed", label);
	}
}
