/*=============================================================================#
 # Copyright (c) 2019, 2020 Stephan Wahlbrink <sw@wahlbrink.eu> and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.rhelp.core.http;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import org.eclipse.statet.jcommons.collections.BasicImMapEntry;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.IntArrayList;
import org.eclipse.statet.jcommons.collections.IntList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;

import org.eclipse.statet.internal.rhelp.core.http.HttpHeaderUtils.MediaTypeEntry;
import org.eclipse.statet.internal.rhelp.core.http.HttpHeaderUtils.ParseException;


@NonNullByDefault
public class HttpHeaderTest {
	
	
	public HttpHeaderTest() {
	}
	
	
	@Test
	public void parseMediaTypes_empty() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("");
		assertEquals(0, entries.size());
		
		entries= parseMediaTypes("  	");
		assertEquals(0, entries.size());
	}
	
	@Test
	public void parseMediaTypes_simple() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("text/plain, text/html, text/x-dvi, */*");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "plain", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("text", "html", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("text", "x-dvi", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("*", "*", 1f, ImCollections.emptyList())
		), entries );
	}
	
	@Test
	public void parseMediaTypes_withQualityFactor() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("text/plain;q=0.1");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "plain", 0.1f, ImCollections.emptyList())
		), entries );
		
		entries= parseMediaTypes("text/plain;   q=0.25");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "plain", 0.25f, ImCollections.emptyList())
		), entries );
		
		entries= parseMediaTypes("text/plain; q=1  ");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "plain", 1f, ImCollections.emptyList())
		), entries );
	}
	
	@Test
	public void parseMediaTypes_withQualityFactor_invalid() throws ParseException {
		Assertions.assertThrows(ParseException.class,
				() -> parseMediaTypes("text/plain;q") );
		
		Assertions.assertThrows(ParseException.class,
				() -> parseMediaTypes("text/plain;q=") );
		
		Assertions.assertThrows(ParseException.class,
				() -> parseMediaTypes("text/plain;q=text") );
	}
	
	@Test
	public void parseMediaTypes_withParameter() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("text/html;level=1");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "html", 1f,  ImCollections.newList(
						new BasicImMapEntry<>("level", "1") ))
		), entries );
		
		entries= parseMediaTypes("application/x.org.eclipse.statet.rhelp-ds; ser=12");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.rhelp-ds", 1f,  ImCollections.newList(
						new BasicImMapEntry<>("ser", "12") ))
		), entries );
		
		entries= parseMediaTypes(" text/html;   level=1	; ext=  test  ");
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "html", 1f,  ImCollections.newList(
						new BasicImMapEntry<>("level", "1"),
						new BasicImMapEntry<>("ext", "test") ))
		), entries );
	}
	
	@Test
	public void parseMediaTypes_precedence_bySpecific() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("text/*, text/html, text/html;level=1, */*");
		entries.sort(null);
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "html", 1f, ImCollections.newList(
						new BasicImMapEntry<>("level", "1"))),
				new MediaTypeEntry("text", "html", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("text", "*", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("*", "*", 1f, ImCollections.emptyList())
		), entries );
	}
	
	@Test
	public void parseMediaTypes_precedence_byQualityFactor() throws ParseException {
		List<MediaTypeEntry> entries;
		
		entries= parseMediaTypes("text/plain;q=0.1, text/html, text/x-dvi;q=0.5");
		entries.sort(null);
		assertMediaTypesEquals(ImCollections.newList(
				new MediaTypeEntry("text", "html", 1f, ImCollections.emptyList()),
				new MediaTypeEntry("text", "x-dvi", 0.5f, ImCollections.emptyList()),
				new MediaTypeEntry("text", "plain", 0.1f, ImCollections.emptyList())
		), entries );
	}
	
	private List<MediaTypeEntry> parseMediaTypes(final String... headers) throws ParseException {
		final List<MediaTypeEntry> entries= new ArrayList<>();
		HttpHeaderUtils.parseMediaTypes(Collections.enumeration(Arrays.asList(headers)),
				null, entries );
		return entries;
	}
	
	private void assertMediaTypesEquals(final List<MediaTypeEntry> expected, final List<MediaTypeEntry> entries) {
		assertEquals(expected.size(), entries.size(), "count");
		for (int i= 0; i < expected.size(); i++) {
			final int i0= i;
			assertEquals(expected.get(i), entries.get(i),
					() -> String.format("media types differ at [%1$s] in basic properties", i0) );
			assertEquals(expected.get(i).getQualityFactor(), entries.get(i).getQualityFactor(), 0f,
					() -> String.format("media types differ at [%1$s] in qualityFactor ", i0) );
		}
	}
	
	
	@Test
	public void findFirstValid() {
		List<MediaTypeEntry> entries;
		int version;
		
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "3") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "2") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> (v == 1));
		assertEquals(1, version);
		
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "3") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "2") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> (v == 3));
		assertEquals(3, version);
		
		final IntList supportedVersions= new IntArrayList();
		supportedVersions.add(4);
		supportedVersions.add(2);
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "3") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "2") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> supportedVersions.contains(v));
		assertEquals(2, version);
	}
	
	@Test
	public void findFirstValid_withMissingSpec() {
		List<MediaTypeEntry> entries;
		int version;
		
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList()),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "2") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> (v == 1));
		assertEquals(1, version);
	}
	
	@Test
	public void findFirstValid_withInvalidSpec() {
		List<MediaTypeEntry> entries;
		int version;
		
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "x") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> (v == 1));
		assertEquals(1, version);
	}
	
	@Test
	public void findFirstValid_noValid() {
		List<MediaTypeEntry> entries;
		int version;
		
		entries= ImCollections.newList(
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.5f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "3") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.2f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "2") )),
				new MediaTypeEntry("application", "x.org.eclipse.statet.test", 0.1f, ImCollections.newList(
						new BasicImMapEntry<>("ver", "1") )) );
		version= HttpHeaderUtils.findFirstValid(entries, "ver", (final int v) -> (v == 4));
		assertEquals(-1, version);
	}
	
	
}
