// ***************************************************************************************************************************
// * 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.a.rttests;

import static org.apache.juneau.testutils.TestUtils.*;
import static org.junit.Assert.*;

import java.util.*;

import javax.xml.datatype.*;

import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.json.annotation.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.transform.*;
import org.apache.juneau.utils.*;
import org.junit.*;

/**
 * Tests designed to serialize and parse objects to make sure we end up
 * with the same objects for all serializers and parsers.
 */
@SuppressWarnings({"unchecked","serial"})
public class RoundTripBeanMapsTest extends RoundTripTest {

	public RoundTripBeanMapsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
		super(label, s, p, flags);
	}

	@Override /* RoundTripTest */
	public Map<Class<?>,Class<?>> getImplClasses() {
		Map<Class<?>,Class<?>> m = new HashMap<>();
		m.put(IBean.class, CBean.class);
		return m;
	}

	//====================================================================================================
	// IBean/ABean/Bean
	//====================================================================================================
	@Test
	public void testImplClasses() throws Exception {
		IBean bean = new CBean();

		bean.setF1("bar");
		bean = roundTrip(bean, IBean.class);
		assertEquals("bar", bean.getF1());

		bean.setF1("baz");
		bean = roundTrip(bean, ABean.class);
		assertEquals("baz", bean.getF1());

		bean.setF1("bing");
		bean = roundTrip(bean, CBean.class);
		assertEquals("bing", bean.getF1());
	}

	//====================================================================================================
	// IBean[]/ABean[]/Bean[]
	//====================================================================================================
	@Test
	public void testImplArrayClasses() throws Exception {
		IBean[] bean = new CBean[]{new CBean()};

		bean[0].setF1("bar");
		bean = roundTrip(bean, IBean[].class);
		assertEquals("bar", bean[0].getF1());

		bean[0].setF1("baz");
		bean = roundTrip(bean, ABean[].class);
		assertEquals("baz", bean[0].getF1());

		bean[0].setF1("bing");
		bean = roundTrip(bean, CBean[].class);
		assertEquals("bing", bean[0].getF1());
	}

	//====================================================================================================
	// List<IBean/ABean/Bean>
	//====================================================================================================
	@Test
	public void testImplListClasses() throws Exception {
		List<IBean> l = AList.<IBean>create(new CBean());

		l.get(0).setF1("bar");
		l = roundTrip(l, List.class, IBean.class);
		assertEquals("bar", l.get(0).getF1());
		l = roundTrip(l, LinkedList.class, IBean.class);
		assertEquals("bar", l.get(0).getF1());

		l.get(0).setF1("baz");
		l = roundTrip(l, List.class, ABean.class);
		assertEquals("baz", l.get(0).getF1());
		l = roundTrip(l, LinkedList.class, ABean.class);
		assertEquals("baz", l.get(0).getF1());

		l.get(0).setF1("bing");
		l = roundTrip(l, List.class, CBean.class);
		assertEquals("bing", l.get(0).getF1());
		l = roundTrip(l, LinkedList.class, CBean.class);
		assertEquals("bing", l.get(0).getF1());
	}

	//====================================================================================================
	// Map<String,IBean/ABean/Bean>
	//====================================================================================================
	@Test
	public void testImplMap() throws Exception {
		Map<String,IBean> l = new AMap<String,IBean>().append("foo", new CBean());

		l.get("foo").setF1("bar");
		l = roundTrip(l, Map.class, String.class, IBean.class);
		assertEquals("bar", l.get("foo").getF1());
		l = roundTrip(l, LinkedHashMap.class, String.class, IBean.class);
		assertEquals("bar", l.get("foo").getF1());

		l.get("foo").setF1("baz");
		l = roundTrip(l, Map.class, String.class, ABean.class);
		assertEquals("baz", l.get("foo").getF1());
		l = roundTrip(l, LinkedHashMap.class, String.class, ABean.class);
		assertEquals("baz", l.get("foo").getF1());

		l.get("foo").setF1("bing");
		l = roundTrip(l, Map.class, String.class, CBean.class);
		assertEquals("bing", l.get("foo").getF1());
		l = roundTrip(l, LinkedHashMap.class, String.class, CBean.class);
		assertEquals("bing", l.get("foo").getF1());
	}

	//====================================================================================================
	// Map<String,IBean/ABean/Bean>
	//====================================================================================================
	@Test
	public void testImplMap2() throws Exception {
		A b = new A(1);
		b = roundTrip(b);
		if (returnOriginalObject || p == null)
			return;
		assertEquals(0, b.f1);
		assertEquals(0, b.f2);
		assertEquals(1, b.f3);
		assertEquals(1, b.f4);
		assertEquals(0, b.getF5());
		assertEquals(1, b.getF6());
	}

	public static interface IBean {
		public String getF1();
		public void setF1(String f1);
	}

	public static abstract class ABean implements IBean {
		@Override /* IBean */
		public abstract String getF1();
		@Override /* IBean */
		public abstract void setF1(String f1);
	}

	public static class CBean extends ABean {
		private String f1 = "foo";
		@Override /* IBean */
		public String getF1() {
			return f1;
		}
		@Override /* IBean */
		public void setF1(String f1) {
			this.f1 = f1;
		}
	}

	public static class A {

		@BeanIgnore
		public int f1, f2;
		public int f3, f4;

		private int f5, f6;

		@BeanIgnore
		public int getF5() {
			return f5;
		}
		public void setF5(int f5) {
			this.f5 = f5;
		}

		public int getF6() {
			return f6;
		}
		public void setF6(int f6) {
			this.f6 = f6;
		}

		public A() {}

		public A(int v) {
			f1 = f2 = f3 = f4 = f5 = f6 = v;
		}
	}

	//====================================================================================================
	// Test @Bean(subTypes=xxx)
	//====================================================================================================
	@Test
	public void testSubTypesUsingAnnotation() throws Exception {
		JsonSerializer js = JsonSerializer.create().ssq().addBeanTypes().addRootType().build();

		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer();
		Parser p = getParser();

		B1 b1 = B1.create();
		Object r = s.serialize(b1);
		B b = p.parse(r, B.class);
		assertTrue(b instanceof B1);
		assertObjectEquals("{_type:'B1',f0:'f0',f1:'f1'}", b, js);

		B2 b2 = B2.create();
		r = s.serialize(b2);
		b = p.parse(r, B.class);
		assertTrue(b instanceof B2);
		assertObjectEquals("{_type:'B2',f0:'f0',f2:1}", b, js);

		B3 b3 = B3.create();
		r = s.serialize(b3);
		b = p.parse(r, B.class);
		assertTrue(b instanceof B3);
		assertObjectEquals("{_type:'B3',f0:'f0',f3:'2001-01-01T12:34:56.789Z'}", b, js);
}

	@Bean(
		dictionary={B1.class,B2.class,B3.class}
	)
	public abstract static class B {
		public String f0 = "f0";
	}

	@Bean(typeName="B1")
	public static class B1 extends B {
		public String f1;
		public static B1 create() {
			B1 b = new B1();
			b.f0 = "f0";
			b.f1 = "f1";
			return b;
		}
	}

	@Bean(typeName="B2")
	public static class B2 extends B {
		public int f2;
		public static B2 create() {
			B2 b = new B2();
			b.f0 = "f0";
			b.f2 = 1;
			return b;
		}
	}

	@Bean(typeName="B3")
	public static class B3 extends B {
		public XMLGregorianCalendar f3;
		public static B3 create() throws Exception {
			B3 b = new B3();
			b.f0 = "f0";
			b.f3 = DatatypeFactory.newInstance().newXMLGregorianCalendar("2001-01-01T12:34:56.789Z");
			return b;
		}
	}

	//====================================================================================================
	// Test @Bean(subTypes=xxx) using BeanFilter
	//====================================================================================================
	@Test
	public void testSubTypesUsingBeanFilter() throws Exception {
		JsonSerializer js = JsonSerializer.create().ssq().build();

		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer().builder().beanFilters(CFilter.class).build();
		Parser p = getParser().builder().beanFilters(CFilter.class).build();

		C1 c1 = C1.create();
		Object r = s.serialize(c1);
		C c = p.parse(r, C.class);
		assertTrue(c instanceof C1);
		assertObjectEquals("{f0:'f0',f1:'f1'}", c, js);

		C2 c2 = C2.create();
		r = s.serialize(c2);
		c = p.parse(r, C.class);
		assertTrue(c instanceof C2);
		assertObjectEquals("{f0:'f0',f2:1}", c, js);

		C3 c3 = C3.create();
		r = s.serialize(c3);
		c = p.parse(r, C.class);
		assertTrue(c instanceof C3);
		assertObjectEquals("{f0:'f0',f3:'2001-01-01T12:34:56.789Z'}", c, js);
	}

	public abstract static class C {
		public String f0;
	}

	public static class C1 extends C {
		public String f1;
		public static C1 create() {
			C1 c = new C1();
			c.f0 = "f0";
			c.f1 = "f1";
			return c;
		}
	}

	public static class C2 extends C {
		public int f2;
		public static C2 create() {
			C2 c = new C2();
			c.f0 = "f0";
			c.f2 = 1;
			return c;
		}
	}

	public static class C3 extends C {
		public XMLGregorianCalendar f3;
		public static C3 create() throws Exception {
			C3 c = new C3();
			c.f0 = "f0";
			c.f3 = DatatypeFactory.newInstance().newXMLGregorianCalendar("2001-01-01T12:34:56.789Z");
			return c;
		}
	}

	public static class CFilter extends BeanFilterBuilder<C> {
		public CFilter() {
			dictionary(CFilterDictionaryMap.class);
		}
	}

	public static class CFilterDictionaryMap extends BeanDictionaryMap {
		public CFilterDictionaryMap() {
			addClass("C1", C1.class);
			addClass("C2", C2.class);
			addClass("C3", C3.class);
		}
	}

	//====================================================================================================
	// Test @Bean(subTypeProperty=xxx) with real bean property
	//====================================================================================================
	@Test
	public void testSubTypePropertyWithRealPropertyUsingAnnotation() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer();
		Parser p = getParser();

		BA1 ba1 = BA1.create();
		Object r = s.serialize(ba1);
		BA b = p.parse(r, BA.class);
		assertTrue(b instanceof BA1);
		assertObjectEquals("{_type:'BA1',f0a:'f0a',f0b:'f0b',f1:'f1'}", b);
	}

	@Bean(dictionary={BA1.class,BA2.class})
	public abstract static class BA {
		public String f0a, f0b;
	}

	@Bean(typeName="BA1")
	public static class BA1 extends BA {
		public String f1;
		public static BA1 create() {
			BA1 b = new BA1();
			b.f0a = "f0a";
			b.f0b = "f0b";
			b.f1 = "f1";
			return b;
		}
	}

	@Bean(typeName="BA2")
	public static class BA2 extends BA {
		public String f2;
	}


	//====================================================================================================
	// Test @Bean(subTypes=xxx) with real bean property using BeanFilter
	//====================================================================================================
	@Test
	public void testSubTypePropertyWithRealPropertyUsingBeanFilter() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer().builder().beanFilters(CAFilter.class).build();
		Parser p = getParser().builder().beanFilters(CAFilter.class).build();

		CA1 c1 = CA1.create();
		Object r = s.serialize(c1);
		CA c = p.parse(r, CA.class);
		assertTrue(c instanceof CA1);
		assertObjectEquals("{f0a:'f0a',f0b:'f0b',f1:'f1'}", c);
	}

	public abstract static class CA {
		public String f0a, f0b;
	}

	public static class CA1 extends CA {
		public String f1;
		public static CA1 create() {
			CA1 c = new CA1();
			c.f0a = "f0a";
			c.f0b = "f0b";
			c.f1 = "f1";
			return c;
		}
	}

	public static class CA2 extends CA {
		public String f2;
	}

	public static class CAFilter extends BeanFilterBuilder<CA> {
		public CAFilter() {
			dictionary(CAFilterDictionaryMap.class);
		}
	}

	public static class CAFilterDictionaryMap extends BeanDictionaryMap {
		public CAFilterDictionaryMap() {
			addClass("CA1", CA1.class);
			addClass("CA2", CA2.class);
		}
	}

	//====================================================================================================
	// Test @Bean(properties=xxx)
	//====================================================================================================
	@Test
	public void testPropertiesUsingAnnotation() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer();
		Parser p = getParser();

		D1 d = new D1().init();
		Object r = s.serialize(d);
		d = p.parse(r, D1.class);
		assertNull(d.f1);
		assertObjectEquals("{f3:'f3',f2:'f2'}", d);
	}

	@Bean(bpi="f3,f2")
	public static class D1 {
		public String f1, f2, f3;
		public D1 init() {
			f1 = "f1";
			f2 = "f2";
			f3 = "f3";
			return this;
		}
	}

	//====================================================================================================
	// Test @Bean(properties=xxx) using BeanFilter
	//====================================================================================================
	@Test
	public void testPropertiesUsingBeanFilter() throws Exception {
		JsonSerializer js = JsonSerializer.create().ssq().beanFilters(D2Filter.class).build();

		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer().builder().beanFilters(D2Filter.class).build();
		Parser p = getParser().builder().beanFilters(D2Filter.class).build();

		D2 d = new D2().init();
		Object r = s.serialize(d);
		d = p.parse(r, D2.class);
		assertNull(d.f1);
		assertObjectEquals("{f3:'f3',f2:'f2'}", d, js);
	}

	public static class D2 {
		public String f1, f2, f3;
		public D2 init() {
			f1 = "f1";
			f2 = "f2";
			f3 = "f3";
			return this;
		}
	}
	public static class D2Filter extends BeanFilterBuilder<D2> {
		public D2Filter() {
			bpi("f3,f2");
		}
	}

	//====================================================================================================
	// Test @Bean(bpx=xxx)
	//====================================================================================================
	@Test
	public void testExcludePropertiesUsingAnnotation() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer();
		Parser p = getParser();

		E1 e = new E1().init();
		Object r = s.serialize(e);
		e = p.parse(r, E1.class);
		assertObjectEquals("{f1:'f1',f3:'f3'}", e);
	}

	@Bean(bpx="f2")
	public static class E1 {
		public String f1, f2, f3;
		public E1 init() {
			f1 = "f1";
			f2 = "f2";
			f3 = "f3";
			return this;
		}
	}

	//====================================================================================================
	// Test @Bean(bpx=xxx) using BeanFilter
	//====================================================================================================
	@Test
	public void testExcludePropertiesUsingBeanFilter() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer().builder().beanFilters(E2Filter.class).build();
		Parser p = getParser().builder().beanFilters(E2Filter.class).build();

		E2 e = new E2().init();
		Object r = s.serialize(e);
		e = p.parse(r, E2.class);
		assertObjectEquals("{f1:'f1',f3:'f3'}", e);
	}

	public static class E2 {
		public String f1, f2, f3;
		public E2 init() {
			f1 = "f1";
			f2 = "f2";
			f3 = "f3";
			return this;
		}
	}
	public static class E2Filter extends BeanFilterBuilder<E2> {
		public E2Filter() {
			bpx("f2");
		}
	}

	//====================================================================================================
	// Test @Bean(interfaceClass=xxx)
	//====================================================================================================
	@Test
	public void testInterfaceClassUsingAnnotation() throws Exception {
		// Skip validation-only tests
		if (isValidationOnly())
			return;

		Serializer s = getSerializer();
		Parser p = getParser();

		FA2 t = new FA2().init();
		Object r = s.serialize(t);
		t = p.parse(r, FA2.class);
		assertObjectEquals("{f1:'f1'}", t);
	}

	@Bean(interfaceClass=FA1.class)
	public static class FA1 {
		public String f1;
	}

	public static class FA2 extends FA1 {
		public String f2;
		public FA2 init() {
			f1 = "f1";
			f2 = "f2";
			return this;
		}
	}

	//====================================================================================================
	// Test @Bean(interfaceClass=xxx) using BeanFilter
	//====================================================================================================
	@Test
	public void testInterfaceClassUsingBeanFilter() throws Exception {
		SerializerBuilder s = getSerializer().builder();
		ParserBuilder p = getParser() == null ? null : getParser().builder();
		FB2 t;
		Object r;

		// Skip validation-only tests
		if (isValidationOnly())
			return;

		// --- BeanFilter defined on parent class ---
		s.beanFilters(FB1Filter.class);
		p.beanFilters(FB1Filter.class);

		t = new FB2().init();
		r = s.build().serialize(t);
		t = p.build().parse(r, FB2.class);
		assertObjectEquals("{f1:'f1'}", t);

		// --- BeanFilter defined on child class class ---
		s.beanFilters(FB2Filter.class);
		p.beanFilters(FB2Filter.class);

		t = new FB2().init();
		r = s.build().serialize(t);
		t = p.build().parse(r, FB2.class);
		assertObjectEquals("{f1:'f1'}", t);

		// --- BeanFilter defined as plain class ---
		s.beanFilters(FB1.class);
		p.beanFilters(FB1.class);

		t = new FB2().init();
		r = s.build().serialize(t);
		t = p.build().parse(r, FB2.class);
		assertObjectEquals("{f1:'f1'}", t);
	}

	public static class FB1 {
		public String f1;
	}

	public static class FB2 extends FB1 {
		public String f2;
		public FB2 init() {
			f1 = "f1";
			f2 = "f2";
			return this;
		}
	}
	public static class FB1Filter extends InterfaceBeanFilterBuilder<FB1> {}
	public static class FB2Filter extends InterfaceBeanFilterBuilder<FB1> {}

	//====================================================================================================
	// testMemberClass
	//====================================================================================================
	@Test
	public void testMemberClass() throws Exception {
		G t = G.create();
		t = roundTrip(t, G.class);
	}

	public static class G {
		public int a1;
		public G1 g1;

		public static G create() {
			G g = new G();
			g.a1 = 1;
			g.g1.a2 = 2;
			g.g1.g2.a3 = 3;
			return g;
		}

		public G() {
			g1 = new G1();
		}

		public class G1 {
			public int a2;
			public G2 g2;

			public G1() {
				g2 = new G2();
			}

			public class G2 {
				public int a3;
			}
		}
	}

	//====================================================================================================
	// testMemberClassWithMapClass
	//====================================================================================================
	@Test
	public void testMemberClassWithMapClass() throws Exception {
		H t = H.create();
		t = roundTrip(t, H.class);
	}

	public static class H extends LinkedHashMap<String,H.H1> {

		static H create() {
			H h = new H();
			h.add("foo", 1, 2);
			return h;
		}

		H add(String key, int a2, int a3) {
			H1 h1 = new H1();
			h1.a2 = a2;
			h1.h2.a3 = a3;
			put(key, h1);
			return this;
		}

		public class H1 {
			public int a2;
			public H2 h2;

			public H1() {
				h2 = new H2();
			}

			public class H2 {
				public int a3;
			}
		}
	}

	//====================================================================================================
	// testMemberClassWithListClass
	//====================================================================================================
	@Test
	public void testMemberClassWithListClass() throws Exception {
		I t = I.create();
		t = roundTrip(t, I.class);
	}

	public static class I extends LinkedList<I.I1> {

		static I create() {
			I i = new I();
			i.add(1, 2);
			return i;
		}

		I add(int a2, int a3) {
			I1 i1 = new I1();
			i1.a2 = a2;
			i1.i2.a3 = a3;
			super.add(i1);
			return this;
		}

		public class I1 {
			public int a2;
			public I2 i2;

			public I1() {
				i2 = new I2();
			}

			public class I2 {
				public int a3;
			}
		}
	}

	//====================================================================================================
	// testMemberClassWithStringConstructor
	//====================================================================================================
	@Test
	public void testMemberClassWithStringConstructor() throws Exception {
		J t = J.create();
		t = roundTrip(t, J.class);
	}

	public static class J {
		public J2 j2;

		static J create() {
			J j = new J();
			j.init();
			return j;
		}

		private void init() {
			j2 = new J2("2");
		}

		public class J2 {
			int a2;

			public J2(String arg) {
				this.a2 = Integer.parseInt(arg);
			}

			@Override /* Object */
			public String toString() {
				return String.valueOf(a2);
			}
		}
	}

	//====================================================================================================
	// testBeanPropertyPrecedence
	//====================================================================================================
	@Test
	public void testBeanPropertyPrecedence() throws Exception {
		K t = K.create();
		t = roundTrip(t, K.class);
	}
	public static enum KEnum { FOO, BAR, BAZ }

	public static class K {
		private KEnum a, b, c;

		static K create() {
			K t = new K();
			t.a = KEnum.FOO;
			t.b = KEnum.BAR;
			t.c = KEnum.BAZ;
			return t;
		}

		@BeanIgnore
		public KEnum getA() {
			return KEnum.FOO;
		}

		@Beanp(name="a")
		public String getA2() {
			return a.toString();
		}

		// This method should not be interpreted as the setter for this
		// property because it doesn't match the getter return type above.
		public void setA(KEnum a) {
			throw new RuntimeException("Should not be called!");
		}

		public void setA(String a) {
			this.a = KEnum.valueOf(a);
		}

		public KEnum getB() {
			return b;
		}

		public void setB(String b) {
			throw new RuntimeException("Should not be called!");
		}

		public void setB(Object b) {
			throw new RuntimeException("Should not be called!");
		}

		public void setB(KEnum b) {
			this.b = b;
		}

		public KEnum getC() {
			return c;
		}

		public void setC(KEnum c) {
			this.c = c;
		}

		public void setC(String c) {
			throw new RuntimeException("Should not be called!");
		}

		public void setC(Object c) {
			throw new RuntimeException("Should not be called!");
		}
	}

	//====================================================================================================
	// testWrapperAttrAnnotationOnBean
	//====================================================================================================
	@Test
	public void testWrapperAttrAnnotationOnBean() throws Exception {
		L t = L.create();
		t = roundTrip(t, L.class);

		Map<String,L> m = new LinkedHashMap<>();
		m.put("bar", L.create());
		roundTrip(m, LinkedHashMap.class, String.class, L.class);
	}

	@Json(wrapperAttr="foo")
	public static class L {
		public int f1;

		static L create() {
			L l = new L();
			l.f1 = 1;
			return l;
		}
	}

	//====================================================================================================
	// testWrapperAttrAnnotationOnNonBean
	//====================================================================================================
	@Test
	public void testWrapperAttrAnnotationOnNonBean() throws Exception {
		M t = M.create();
		t = roundTrip(t, M.class);

		Map<String,M> m = new LinkedHashMap<>();
		m.put("bar", M.create());
		roundTrip(m, LinkedHashMap.class, String.class, M.class);
	}

	@Json(wrapperAttr="foo")
	public static class M {
		int f1;

		static M create() {
			M m = new M();
			m.f1 = 1;
			return m;
		}

		@Override /* Object */
		public String toString() {
			return String.valueOf(f1);
		}

		public static M valueOf(String s) {
			M m = new M();
			m.f1 = Integer.parseInt(s);
			return m;
		}
	}
}
