// ***************************************************************************************************************************
// * 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.json;

import static org.apache.juneau.testutils.TestUtils.*;
import static org.junit.Assert.*;

import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.json.annotation.*;
import org.apache.juneau.serializer.*;
import org.junit.*;

@SuppressWarnings({"serial"})
public class JsonTest {

	//====================================================================================================
	// testBasic
	//====================================================================================================
	@Test
	public void testBasic() throws Exception {
		Map<String,Object> m = new LinkedHashMap<>();
		List<Object> l = new LinkedList<>();

		WriterSerializer s1 = JsonSerializer.create().ssq().trimNullProperties(false).build();
		WriterSerializer s2 = JsonSerializer.create().simple().trimNullProperties(false).build();
		String r;

		// Null keys and values
		m.clear();
		m.put(null, null);
		m.put("aaa", "bbb");
		assertEquals("A1", "{null:null,aaa:'bbb'}", s1.serialize(m));

		// Escapes.
		// String = ["]
		m.clear();
		m.put("x", "[\"]");
		assertEquals("{x:\"[\\\"]\"}", s2.serialize(m));
		// String = [\"]
		// JSON = {x:"\\\""}
		m.clear();
		m.put("x", "[\\\"]");
		assertEquals("{x:\"[\\\\\\\"]\"}", s2.serialize(m));

		// String = [\w[\w\-\.]{3,}\w]
		// JSON = {x:"\\w[\\w\\-\\.]{3,}\\w"}
		m.clear();
		r = "\\w[\\w\\-\\.]{3,}\\w";
		m.put("x", r);
		assertEquals("{x:\"\\\\w[\\\\w\\\\-\\\\.]{3,}\\\\w\"}", s2.serialize(m));
		assertEquals(r, new ObjectMap(s2.serialize(m)).getString("x"));

		// String = [foo\bar]
		// JSON = {x:"foo\\bar"}
		m.clear();
		m.put("x", "foo\\bar");
		assertEquals("{x:\"foo\\\\bar\"}", s2.serialize(m));

		m.clear();
		m.put("null", null);
		m.put("aaa", "bbb");
		assertEquals("A2", "{'null':null,aaa:'bbb'}", s1.serialize(m));

		m.clear();
		m.put(null, "null");
		m.put("aaa", "bbb");
		assertEquals("A3", "{null:'null',aaa:'bbb'}", s1.serialize(m));

		// Arrays
		m.clear();
		l.clear();
		m.put("J", "f1");
		m.put("B", "b");
		m.put("C", "c");
		l.add("1");
		l.add("2");
		l.add("3");
		Object o = new Object[] { m, l };
		Object o2 = new Object[] { o, "foo", "bar", new Integer(1), new Boolean(false), new Float(1.2), null };
		assertEquals("K1", "[[{J:'f1',B:'b',C:'c'},['1','2','3']],'foo','bar',1,false,1.2,null]", s1.serialize(o2));
	}

	@Test
	public void testReservedKeywordAttributes() throws Exception {
		Map<String,Object> m = new LinkedHashMap<>();

		// Keys with reserved names.
		for (String attr : new String[]{"","true","false","null","try","123","1x","-123",".123"}) {
			m.clear();
			m.put(attr,1);
			assertObjectEquals("{'"+attr+"':1}", m);
		}
	}

	//====================================================================================================
	// Validate various backslashes in strings.
	//====================================================================================================
	@Test
	public void testBackslashesInStrings() throws Exception {
		JsonSerializer s = JsonSerializer.create().simple().trimNullProperties(false).build();
		String r, r2;

		// [\\]
		r = "\\";
		r2 = s.serialize(r);
		assertEquals(r2, "\"\\\\\"");
		assertEquals(JsonParser.DEFAULT.parse(r2, Object.class), r);

		// [\b\f\n\t]
		r = "\b\f\n\t";
		r2 = s.serialize(r);
		assertEquals("\"\\b\\f\\n\\t\"", r2);
		assertEquals(r, JsonParser.DEFAULT.parse(r2, Object.class));

		// Special JSON case:  Forward slashes can OPTIONALLY be escaped.
		// [\/]
		assertEquals(JsonParser.DEFAULT.parse("\"\\/\"", Object.class), "/");

		// Unicode
		r = "\u1234\u1ABC\u1abc";
		r2 = s.serialize(r);
		assertEquals("\"\u1234\u1ABC\u1abc\"", r2);

		assertEquals("\u1234", JsonParser.DEFAULT.parse("\"\\u1234\"", Object.class));
	}

	//====================================================================================================
	// Indentation
	//====================================================================================================
	@Test
	public void testIndentation() throws Exception {
		ObjectMap m = new ObjectMap("{J:{B:['c',{D:'e'},['f',{G:'h'},1,false]]},I:'j'}");
		String e = ""
			+ "{"
			+ "\n	J: {"
			+ "\n		B: ["
			+ "\n			'c',"
			+ "\n			{"
			+ "\n				D: 'e'"
			+ "\n			},"
			+ "\n			["
			+ "\n				'f',"
			+ "\n				{"
			+ "\n					G: 'h'"
			+ "\n				},"
			+ "\n				1,"
			+ "\n				false"
			+ "\n			]"
			+ "\n		]"
			+ "\n	},"
			+ "\n	I: 'j'"
			+ "\n}";
		assertEquals(e, SimpleJsonSerializer.DEFAULT_READABLE.serialize(m));
	}

	//====================================================================================================
	// Escaping double quotes
	//====================================================================================================
	@Test
	public void testEscapingDoubleQuotes() throws Exception {
		JsonSerializer s = JsonSerializer.DEFAULT;
		String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
		assertEquals("{\"f1\":\"x'x\\\"x\"}", r);
		JsonParser p = JsonParser.DEFAULT;
		assertEquals("x'x\"x", p.parse(r, ObjectMap.class).getString("f1"));
	}

	//====================================================================================================
	// Escaping single quotes
	//====================================================================================================
	@Test
	public void testEscapingSingleQuotes() throws Exception {
		JsonSerializer s = SimpleJsonSerializer.DEFAULT;
		String r = s.serialize(new ObjectMap().append("f1", "x'x\"x"));
		assertEquals("{f1:'x\\'x\"x'}", r);
		JsonParser p = JsonParser.DEFAULT;
		assertEquals("x'x\"x", p.parse(r, ObjectMap.class).getString("f1"));
	}

	//====================================================================================================
	// testWrapperAttrAnnotationOnBean
	//====================================================================================================
	@Test
	public void testWrapperAttrAnnotationOnBean() throws Exception {
		JsonSerializer s = SimpleJsonSerializer.DEFAULT;
		JsonParser p = JsonParser.DEFAULT;
		String r;

		A t = A.create();
		r = s.serialize(t);
		assertEquals("{foo:{f1:1}}", r);
		t = p.parse(r, A.class);
		assertEquals(1, t.f1);

		Map<String,A> m = new LinkedHashMap<>();
		m.put("bar", A.create());
		r = s.serialize(m);
		assertEquals("{bar:{foo:{f1:1}}}", r);

		m = p.parse(r, LinkedHashMap.class, String.class, A.class);
		assertEquals(1, m.get("bar").f1);
	}

	@Json(wrapperAttr="foo")
	public static class A {
		public int f1;

		static A create() {
			A a = new A();
			a.f1 = 1;
			return a;
		}
	}

	@Test
	public void testWrapperAttrAnnotationOnBean_usingConfig() throws Exception {
		JsonSerializer s = SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(A2.class).build();
		JsonParser p = JsonParser.DEFAULT.builder().applyAnnotations(A2.class).build();
		String r;

		A2 t = A2.create();
		r = s.serialize(t);
		assertEquals("{foo:{f1:1}}", r);
		t = p.parse(r, A2.class);
		assertEquals(1, t.f1);

		Map<String,A2> m = new LinkedHashMap<>();
		m.put("bar", A2.create());
		r = s.serialize(m);
		assertEquals("{bar:{foo:{f1:1}}}", r);

		m = p.parse(r, LinkedHashMap.class, String.class, A2.class);
		assertEquals(1, m.get("bar").f1);
	}

	@JsonConfig(applyJson=@Json(on="A2",wrapperAttr="foo"))
	public static class A2 {
		public int f1;

		static A2 create() {
			A2 a = new A2();
			a.f1 = 1;
			return a;
		}
	}

	//====================================================================================================
	// testWrapperAttrAnnotationOnNonBean
	//====================================================================================================
	@Test
	public void testWrapperAttrAnnotationOnNonBean() throws Exception {
		JsonSerializer s = SimpleJsonSerializer.DEFAULT;
		JsonParser p = JsonParser.DEFAULT;
		String r;

		B t = B.create();
		r = s.serialize(t);
		assertEquals("{foo:'1'}", r);
		t = p.parse(r, B.class);
		assertEquals(1, t.f1);

		Map<String,B> m = new LinkedHashMap<>();
		m.put("bar", B.create());
		r = s.serialize(m);
		assertEquals("{bar:{foo:'1'}}", r);

		m = p.parse(r, LinkedHashMap.class, String.class, B.class);
		assertEquals(1, m.get("bar").f1);
	}

	@Json(wrapperAttr="foo")
	public static class B {
		int f1;

		static B create() {
			B b = new B();
			b.f1 = 1;
			return b;
		}

		@Override /* Object */
		public String toString() {
			return String.valueOf(f1);
		}

		public static B valueOf(String s) {
			B b = new B();
			b.f1 = Integer.parseInt(s);
			return b;
		}
	}

	@Test
	public void testWrapperAttrAnnotationOnNonBean_usingConfig() throws Exception {
		JsonSerializer s = SimpleJsonSerializer.DEFAULT.builder().applyAnnotations(B2.class).build();
		JsonParser p = JsonParser.DEFAULT.builder().applyAnnotations(B2.class).build();;
		String r;

		B2 t = B2.create();
		r = s.serialize(t);
		assertEquals("{foo:'1'}", r);
		t = p.parse(r, B2.class);
		assertEquals(1, t.f1);

		Map<String,B2> m = new LinkedHashMap<>();
		m.put("bar", B2.create());
		r = s.serialize(m);
		assertEquals("{bar:{foo:'1'}}", r);

		m = p.parse(r, LinkedHashMap.class, String.class, B2.class);
		assertEquals(1, m.get("bar").f1);
	}

	@JsonConfig(applyJson=@Json(on="B2",wrapperAttr="foo"))
	public static class B2 {
		int f1;

		static B2 create() {
			B2 b = new B2();
			b.f1 = 1;
			return b;
		}

		@Override /* Object */
		public String toString() {
			return String.valueOf(f1);
		}

		public static B2 valueOf(String s) {
			B2 b = new B2();
			b.f1 = Integer.parseInt(s);
			return b;
		}
	}

	//====================================================================================================
	// testSubclassedList
	//====================================================================================================
	@Test
	public void testSubclassedList() throws Exception {
		JsonSerializer s = JsonSerializer.DEFAULT;
		Map<String,Object> o = new HashMap<>();
		o.put("c", new C());
		assertEquals("{\"c\":[]}", s.serialize(o));
	}

	public static class C extends LinkedList<String> {
	}

	//====================================================================================================
	// testEscapeSolidus
	//====================================================================================================
	@Test
	public void testEscapeSolidus() throws Exception {
		JsonSerializer s = JsonSerializer.create().escapeSolidus(false).build();
		String r = s.serialize("foo/bar");
		assertEquals("\"foo/bar\"", r);
		r = JsonParser.DEFAULT.parse(r, String.class);
		assertEquals("foo/bar", r);

		s = JsonSerializer.create().escapeSolidus(true).build();
		r = s.serialize("foo/bar");
		assertEquals("\"foo\\/bar\"", r);
		r = JsonParser.DEFAULT.parse(r, String.class);
		assertEquals("foo/bar", r);

		s = JsonSerializer.create().escapeSolidus().build();
		r = s.serialize("foo/bar");
		assertEquals("\"foo\\/bar\"", r);
		r = JsonParser.DEFAULT.parse(r, String.class);
		assertEquals("foo/bar", r);
	}
}