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

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import static org.junit.Assert.*;

import java.lang.annotation.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import org.apache.juneau.annotation.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.junit.*;

/**
 * ParamInfo tests.
 */
public class ParamInfoTest {

	@Documented
	@Target(METHOD)
	@Retention(RUNTIME)
	@Inherited
	public static @interface A {
		String value();
	}

	@Documented
	@Target(METHOD)
	@Retention(RUNTIME)
	@Inherited
	public static @interface AX {
		String value();
	}

	private static void check(String expected, Object o) {
		assertEquals(expected, TO_STRING.apply(o));
	}

	private static final Function<Object,String> TO_STRING = new Function<Object,String>() {
		@Override
		public String apply(Object t) {
			if (t == null)
				return null;
			if (t instanceof List)
				return ((List<?>)t).stream().map(this).collect(Collectors.joining(","));
			if (t.getClass().isArray())
				return StreamSupport.stream(ArrayUtils.toList(t, Object.class).spliterator(), false).map(this).collect(Collectors.joining(","));
			if (t instanceof MethodInfo)
				return ((MethodInfo)t).getDeclaringClass().getSimpleName() + '.' + ((MethodInfo)t).getShortName();
			if (t instanceof CA)
				return "@CA(" + ((CA)t).value() + ")";
			if (t instanceof DA)
				return "@DA(" + ((DA)t).value() + ")";
			if (t instanceof ClassInfo)
				return ((ClassInfo)t).getSimpleName();
			return t.toString();
		}
	};

	//-----------------------------------------------------------------------------------------------------------------
	// Instantiation.
	//-----------------------------------------------------------------------------------------------------------------

	static class B {
		public B(int a, String b) {}
		public void a1(int a, String b) {}
		void a2(int a, String b) {}
	}

	static ClassInfo b = ClassInfo.of(B.class);
	static ParamInfo
		b_b_a = b.getPublicConstructor(int.class, String.class).getParam(0),
		b_b_b = b.getPublicConstructor(int.class, String.class).getParam(1),
		b_a1_a = b.getMethod("a1", int.class, String.class).getParam(0),
		b_a1_b = b.getMethod("a1", int.class, String.class).getParam(1),
		b_a2_a = b.getMethod("a2", int.class, String.class).getParam(0),
		b_a2_b = b.getMethod("a2", int.class, String.class).getParam(1);


	@Test
	public void getIndex() {
		assertEquals(0, b_b_a.getIndex());
		assertEquals(1, b_b_b.getIndex());
		assertEquals(0, b_a1_a.getIndex());
		assertEquals(1, b_a1_b.getIndex());
		assertEquals(0, b_a2_a.getIndex());
		assertEquals(1, b_a2_b.getIndex());
	}

	@Test
	public void getMethod() {
		check("B.a1(int,String)", b_a1_a.getMethod());
		check("B.a1(int,String)", b_a1_b.getMethod());
		check("B.a2(int,String)", b_a2_a.getMethod());
		check("B.a2(int,String)", b_a2_b.getMethod());
	}

	@Test
	public void getMethod_onConstrutor() {
		check(null, b_b_a.getMethod());
		check(null, b_b_b.getMethod());
	}

	@Test
	public void getConstructor() {
		check("B(int,String)", b_b_a.getConstructor());
		check("B(int,String)", b_b_b.getConstructor());
	}

	@Test
	public void getConstructor_onMethod() {
		check(null, b_a1_a.getConstructor());
		check(null, b_a1_b.getConstructor());
		check(null, b_a2_a.getConstructor());
		check(null, b_a2_b.getConstructor());
	}

	@Test
	public void getParameterType() {
		check("int", b_b_a.getParameterType());
		check("String", b_b_b.getParameterType());
		check("int", b_a1_a.getParameterType());
		check("String", b_a1_b.getParameterType());
		check("int", b_a2_a.getParameterType());
		check("String", b_a2_b.getParameterType());

	}

	//-----------------------------------------------------------------------------------------------------------------
	// Annotations.
	//-----------------------------------------------------------------------------------------------------------------

	@Target({PARAMETER,TYPE})
	@Retention(RUNTIME)
	public static @interface CA {
		public String value();
	}
	@CA("1") public static class C1 extends C2 {}
	@CA("2") public static class C2 implements C3, C4 {}
	@CA("3") public static interface C3 {}
	@CA("4") public static interface C4 {}

	public static interface CB {
		public void a1(@CA("5") C1 x);
		public void a2(@CA("5") C1 x);
	}
	public static class CC implements CB {
		public CC(@CA("9") C1 x) {}
		@Override
		public void a1(C1 x) {}
		@Override
		public void a2(@CA("6") C1 x) {}
	}
	static ClassInfo
		cb = ClassInfo.of(CB.class),
		cc = ClassInfo.of(CC.class);
	static ParamInfo
		cc_cc = cc.getPublicConstructor(C1.class).getParam(0),
		cb_a1 = cb.getMethod("a1", C1.class).getParam(0),
		cb_a2 = cb.getMethod("a2", C1.class).getParam(0),
		cc_a1 = cc.getMethod("a1", C1.class).getParam(0),
		cc_a2 = cc.getMethod("a2", C1.class).getParam(0);

	@Test
	public void getDeclaredAnnotations() throws Exception {
		check("@CA(5)", cb_a1.getDeclaredAnnotations());
		check("@CA(5)", cb_a2.getDeclaredAnnotations());
		check("", cc_a1.getDeclaredAnnotations());
		check("@CA(6)", cc_a2.getDeclaredAnnotations());
	}

	@Test
	public void getDeclaredAnnotations_constructor() throws Exception {
		check("@CA(9)", cc_cc.getDeclaredAnnotations());
	}

	@Test
	public void getDeclaredAnnotation() throws Exception {
		check("@CA(5)", cb_a1.getDeclaredAnnotation(CA.class));
		check("@CA(5)", cb_a2.getDeclaredAnnotation(CA.class));
		check(null, cc_a1.getDeclaredAnnotation(CA.class));
		check("@CA(6)", cc_a2.getDeclaredAnnotation(CA.class));
	}

	@Test
	public void getDeclaredAnnotation_constructor() throws Exception {
		check("@CA(9)", cc_cc.getDeclaredAnnotation(CA.class));
	}

	@Test
	public void getDeclaredAnnotation_notFound() throws Exception {
		check(null, cb_a1.getDeclaredAnnotation(DA.class));
	}

	@Test
	public void getDeclaredAnnotation_notFound_constructor() throws Exception {
		check(null, cc_cc.getDeclaredAnnotation(DA.class));
	}

	@Test
	public void getDeclaredAnnotation_null() throws Exception {
		check(null, cb_a1.getDeclaredAnnotation(null));
	}

	@Test
	public void getDeclaredAnnotation_null_constructor() throws Exception {
		check(null, cc_cc.getDeclaredAnnotation(null));
	}

	@Test
	public void getAnnotations() throws Exception {
		check("@CA(5),@CA(1),@CA(2),@CA(3),@CA(4)", cb_a1.getAnnotations(CA.class));
		check("@CA(5),@CA(1),@CA(2),@CA(3),@CA(4)", cb_a2.getAnnotations(CA.class));
		check("@CA(5),@CA(1),@CA(2),@CA(3),@CA(4)", cc_a1.getAnnotations(CA.class));
		check("@CA(6),@CA(5),@CA(1),@CA(2),@CA(3),@CA(4)", cc_a2.getAnnotations(CA.class));
	}

	@Test
	public void getAnnotations_notFound() throws Exception {
		check("", cb_a1.getAnnotations(DA.class));
	}

	@Test
	public void getAnnotations_constructor() throws Exception {
		check("@CA(9),@CA(1),@CA(2),@CA(3),@CA(4)", cc_cc.getAnnotations(CA.class));
	}

	@Test
	public void getAnnotations_notFound_constructor() throws Exception {
		check("", cc_cc.getAnnotations(DA.class));
	}

	@Test
	public void getAnnotationsParentFirst() throws Exception {
		check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", cb_a1.getAnnotationsParentFirst(CA.class));
		check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", cb_a2.getAnnotationsParentFirst(CA.class));
		check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5)", cc_a1.getAnnotationsParentFirst(CA.class));
		check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(5),@CA(6)", cc_a2.getAnnotationsParentFirst(CA.class));
	}

	@Test
	public void getAnnotationsParentFirst_notFound() throws Exception {
		check("", cb_a1.getAnnotationsParentFirst(DA.class));
	}

	@Test
	public void getAnnotationsParentFirst_constructor() throws Exception {
		check("@CA(4),@CA(3),@CA(2),@CA(1),@CA(9)", cc_cc.getAnnotationsParentFirst(CA.class));
	}

	@Test
	public void getAnnotationsParentFirst_notFound_constructor() throws Exception {
		check("", cc_cc.getAnnotationsParentFirst(DA.class));
	}

	@Test
	public void getAnnotation() throws Exception {
		check("@CA(5)", cb_a1.getAnnotation(CA.class));
		check("@CA(5)", cb_a2.getAnnotation(CA.class));
		check("@CA(5)", cc_a1.getAnnotation(CA.class));
		check("@CA(6)", cc_a2.getAnnotation(CA.class));
	}

	@Test
	public void getAnnotation_notFound() throws Exception {
		check(null, cb_a1.getAnnotation(DA.class));
	}

	@Test
	public void getAnnotation_constructor() throws Exception {
		check("@CA(9)", cc_cc.getAnnotation(CA.class));
	}

	@Test
	public void getAnnotation_notFound_constructor() throws Exception {
		check(null, cc_cc.getAnnotation(DA.class));
	}

	@Test
	public void getAnnotation_twice() throws Exception {
		check("@CA(5)", cb_a1.getAnnotation(CA.class));
		check("@CA(5)", cb_a1.getAnnotation(CA.class));
	}

	@Test
	public void getAnnotation_twice_constructor() throws Exception {
		check("@CA(9)", cc_cc.getAnnotation(CA.class));
		check("@CA(9)", cc_cc.getAnnotation(CA.class));
	}

	@Test
	public void hasAnnotation() throws Exception {
		assertTrue(cb_a1.hasAnnotation(CA.class));
		assertTrue(cb_a2.hasAnnotation(CA.class));
		assertTrue(cc_a1.hasAnnotation(CA.class));
		assertTrue(cc_a2.hasAnnotation(CA.class));
		assertFalse(cb_a1.hasAnnotation(DA.class));
	}

	@Test
	public void hasAnnotation_constructor() throws Exception {
		assertTrue(cc_cc.hasAnnotation(CA.class));
		assertFalse(cc_cc.hasAnnotation(DA.class));
	}

	@Target({PARAMETER,TYPE})
	@Retention(RUNTIME)
	@Inherited
	public static @interface DA {
		public String value();
	}
	@DA("1") public static class D1 extends D2 {}
	@DA("2") public static class D2 implements D3, D4 {}
	@DA("3") public static interface D3 {}
	@DA("4") public static interface D4 {}

	public static interface DB {
		public void a1(@DA("0") D1 x);
	}
	public static class DC implements DB {
		@Override
		public void a1(@DA("5") D1 x) {}
	}

	static ClassInfo
		db = ClassInfo.of(DB.class),
		dc = ClassInfo.of(DC.class);
	static ParamInfo
		db_a1 = db.getMethod("a1", D1.class).getParam(0),
		dc_a1 = dc.getMethod("a1", D1.class).getParam(0);

	@Test
	public void getAnnotations_inherited() throws Exception {
		check("@DA(0),@DA(1),@DA(2),@DA(3),@DA(4)", db_a1.getAnnotations(DA.class));
		check("@DA(5),@DA(0),@DA(1),@DA(2),@DA(3),@DA(4)", dc_a1.getAnnotations(DA.class));
	}

	@Test
	public void getAnnotations_inherited_notFound() throws Exception {
		check("", db_a1.getAnnotations(CA.class));
	}

	@Test
	public void getAnnotationsParentFirst_inherited() throws Exception {
		check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0)", db_a1.getAnnotationsParentFirst(DA.class));
		check("@DA(4),@DA(3),@DA(2),@DA(1),@DA(0),@DA(5)", dc_a1.getAnnotationsParentFirst(DA.class));
	}

	@Test
	public void getAnnotationsParentFirst_inherited_notFound() throws Exception {
		check("", db_a1.getAnnotationsParentFirst(CA.class));
	}

	@Test
	public void getAnnotation_inherited() throws Exception {
		check("@DA(0)", db_a1.getAnnotation(DA.class));
		check("@DA(5)", dc_a1.getAnnotation(DA.class));
	}

	@Test
	public void getAnnotation_inherited_notFound() throws Exception {
		check(null, db_a1.getAnnotation(CA.class));
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Other methods.
	//-----------------------------------------------------------------------------------------------------------------

	static class E {
		public void a1(int a, @Name("b") int b) {}
	}

	static ClassInfo e = ClassInfo.of(E.class);
	static ParamInfo
		e_a1_a = e.getMethod("a1", int.class, int.class).getParam(0),
		e_a1_b = e.getMethod("a1", int.class, int.class).getParam(1);

	@Test
	public void hasName() {
		e_a1_a.hasName();  // This might be true or false based on the JVM compiler used.
		assertTrue(e_a1_b.hasName());
	}

	@Test
	public void getName() {
		e_a1_a.getName();  // This might be null or a value based on the JVM compiler used.
		assertEquals("b", e_a1_b.getName());
	}

	@Test
	public void toString2() {
		assertEquals("a1[1]", e_a1_b.toString());
	}
}
