/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed 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 com.alibaba.dubbo.common.serialize.dubbo;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;

import java.io.Serializable;
import java.lang.reflect.Modifier;
import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import com.alibaba.dubbo.common.io.Bytes;
import com.alibaba.dubbo.common.io.UnsafeByteArrayOutputStream;
import com.alibaba.dubbo.common.serialize.support.dubbo.Builder;

public class BuilderTest
{
    @Test
	public void testPrimaryTypeBuilder() throws Exception
	{
		System.out.println((new byte[2]).hashCode());
		Builder<String> builder = Builder.register(String.class);
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		String v = "123";
		builder.writeTo(v, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		v = builder.parseFrom(b);
		builder.writeTo(v, os);
		b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
	}

    @Test
	public void testEnumBuilder() throws Exception
	{
		Builder<Type> builder = Builder.register(Type.class);
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		Type v = Type.High;
		builder.writeTo(v, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		v = builder.parseFrom(b);
	}

    @Test
	public void testThrowableBuilder() throws Exception
	{
		Builder<Throwable> builder = Builder.register(Throwable.class);
		Throwable th = new Throwable();
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		builder.writeTo(th, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));

		th = builder.parseFrom(b);
	}

    @Test
	public void testArrayClassBuilder() throws Exception
	{
		UnsafeByteArrayOutputStream os;

		byte[] b;

		Builder<Object[]> osb = Builder.register(Object[].class);
		os = new UnsafeByteArrayOutputStream();
		osb.writeTo(new Object[]{ new String[0] }, os);
		b = os.toByteArray();

		Builder<long[]> lsb = Builder.register(long[].class);
		os = new UnsafeByteArrayOutputStream();
		lsb.writeTo(new long[]{ 1,121232,-3,4,-5,61321432413l }, os);
		lsb.writeTo(new long[]{ 1,121232,-3,4,-5,61321432413l }, os);
		lsb.writeTo(new long[]{ 1,2,3,12131314,123132313135l,-6 }, os);
		b = os.toByteArray();
		long[] ls = lsb.parseFrom(b);
		assertEquals(ls.length, 6);

		Builder<byte[]> bsb = Builder.register(byte[].class);
		os = new UnsafeByteArrayOutputStream();
		bsb.writeTo("i am a string.".getBytes(), os);
		b = os.toByteArray();

		Builder<int[][]> iisb = Builder.register(int[][].class);
		os = new UnsafeByteArrayOutputStream();
		iisb.writeTo(new int[][]{ {1,2,3,4}, {5,6,7,8}, {9,10}, {122,123,444} }, os);
		b = os.toByteArray();
		int[][] iis = iisb.parseFrom(b);
		assertEquals(iis.length, 4);

		Builder<int[][][]> iiisb = Builder.register(int[][][].class);
		os = new UnsafeByteArrayOutputStream();
		iiisb.writeTo(new int[][][]{ 
			{{1,2,3,4}},
			{{5,6,7,8}},
			{{122,123,444}}
		}, os);
		b = os.toByteArray();
		int[][][] iii = iiisb.parseFrom(b);
		assertEquals(iii.length, 3);
	}

    @Test
	public void testObjectBuilder() throws Exception
	{
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		Builder<Bean> BeanBuilder = Builder.register(Bean.class);

		Bean bean = new Bean();
		bean.name = "ql";
		bean.type = Type.High;
		bean.types = new Type[]{ Type.High, Type.High };
		BeanBuilder.writeTo(bean, os);

		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));

		bean = BeanBuilder.parseFrom(b);
		assertNull(bean.time);
		assertEquals(bean.i, 123123);
		assertEquals(bean.ni, -12344);
		assertEquals(bean.d, 12.345);
		assertEquals(bean.nd, -12.345);
		assertEquals(bean.l, 1281447759383l);
		assertEquals(bean.nl, -13445l);
		assertEquals(bean.vl, 100l);
		assertEquals(bean.type, Type.High);
		assertEquals(bean.types.length, 2);
		assertEquals(bean.types[0], Type.High);
		assertEquals(bean.types[1], Type.High);
		assertEquals(bean.list.size(), 3);
		assertEquals(bean.list.get(0), 1);
		assertEquals(bean.list.get(1), 2);
		assertEquals(bean.list.get(2), 1308147);
	}

    @Test
	public void testInterfaceBuilder() throws Exception
	{
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		Builder<TestDO> builder = Builder.register(TestDO.class);
		TestDO d = new TestDOImpl();
		builder.writeTo(d, os);

		byte[] b = os.toByteArray();

		d = builder.parseFrom(b);
		assertTrue(TestDO.class.isAssignableFrom(d.getClass()));
		assertEquals("name", d.getName());
		assertEquals(28, d.getArg());
		assertEquals(Type.High, d.getType());
	}

    @Test
	public void testGenericBuilder() throws Exception
	{
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		Builder<Object> ob = Builder.register(Object.class);

		Object o = new Object();
		ob.writeTo(o, os);
		byte[] b = os.toByteArray();

		os = new UnsafeByteArrayOutputStream();
		Bean bean = new Bean();
		bean.name = "ql";
		bean.type = Type.High;
		bean.types = new Type[]{ Type.High, Type.High };
		ob.writeTo(bean, os);

		b = os.toByteArray();
		bean = (Bean)ob.parseFrom(b);
		assertEquals(bean.i, 123123);
		assertEquals(bean.ni, -12344);
		assertEquals(bean.d, 12.345);
		assertEquals(bean.nd, -12.345);
		assertEquals(bean.l, 1281447759383l);
		assertEquals(bean.nl, -13445l);
		assertEquals(bean.vl, 100l);
		assertEquals(bean.type, Type.High);
		assertEquals(bean.types.length, 2);
		assertEquals(bean.types[0], Type.High);
		assertEquals(bean.types[1], Type.High);
		assertEquals(bean.list.size(), 3);
		assertEquals(bean.list.get(0), 1);
		assertEquals(bean.list.get(1), 2);
		assertEquals(bean.list.get(2), 1308147);
	}

    @Test
	public void testObjectArrayBuilder() throws Exception
	{
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		Builder<Object[]> builder = Builder.register(Object[].class);

		Object[] obj = new Object[5];
		obj[0] = "1234";
		obj[1] = new Double(109.23);
		obj[2] = "3455";
		obj[3] = null;
		obj[4] = Boolean.TRUE;

		builder.writeTo(obj, os);
		byte[] b = os.toByteArray();
		System.out.println("Object array:"+b.length+":"+Bytes.bytes2hex(b));

		Assert.assertArrayEquals(obj, builder.parseFrom(b));
	}

    // FIXME MyList的从ArrayList中继承来的属性size会在decode时设置好，再Add时就不对了！！
    @Ignore
    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testBuilder_MyList() throws Exception
	{
        Builder<MyList> b1 = Builder.register(MyList.class);
		MyList list = new MyList();
		list.add(new boolean[]{ true,false });
		list.add(new int[]{ 1,2,3,4,5 });
		list.add("String");
		list.add(4);
		list.code = 4321;
		
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
		b1.writeTo(list, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		MyList result = b1.parseFrom(b);

		assertEquals(4, result.size());
		assertEquals(result.code, 4321);
		assertEquals(result.id, "feedback");
	}
    
    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testBuilder_MyMap() throws Exception
    {
        UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();
        Builder<MyMap> b2 = Builder.register(MyMap.class);
        MyMap map = new MyMap();
        map.put("name", "qianlei");
        map.put("displayName", "钱磊");
        map.code = 4321;
        b2.writeTo(map, os);
        byte[] b = os.toByteArray();
        System.out.println(b.length+":"+Bytes.bytes2hex(b));
        
        map = b2.parseFrom(b);
        
        assertEquals(map.size(), 2);
        assertEquals(map.code, 4321);
        assertEquals(map.id, "feedback");
    }

    @Test
	@SuppressWarnings("unchecked")
	public void testSerializableBean() throws Exception
	{
		System.out.println("testSerializableBean");
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();

		SerializableBean sb = new SerializableBean();
		Builder<SerializableBean> sbb = Builder.register(SerializableBean.class);
		sbb.writeTo(sb, os);

		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		assertEquals(sbb.parseFrom(os.toByteArray()), sb);
	}

    @Test
	@SuppressWarnings("unchecked")
	public void testOthers() throws Exception
	{
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();

		StringBuffer buf = new StringBuffer();
		for(int i=0;i<1024*32+32;i++)
			buf.append('A');
		Builder<String> sb = Builder.register(String.class);
		sb.writeTo(buf.toString(), os);
		assertEquals(sb.parseFrom(os.toByteArray()), buf.toString());

		os = new UnsafeByteArrayOutputStream();
		Builder<HashMap> builder = Builder.register(HashMap.class);
		Map services = new HashMap();
		HashMap map = new HashMap();
		services.put("test.service", "http://127.0.0.1:9010/test.service");
		map.put("name", "qianlei");
		map.put("password", "123455");
		map.put("services", services);

		builder.writeTo(map, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		map = builder.parseFrom(b);
		assertTrue(map.size() > 0);
        assertEquals("http://127.0.0.1:9010/test.service", ((Map) map.get("services")).get("test.service"));

		services = new ConcurrentHashMap();
		services.put("test.service", "http://127.0.0.1:9010/test.service");
		map.put("services", services);

		os = new UnsafeByteArrayOutputStream();
		builder.writeTo(map, os);
		b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));
		map = builder.parseFrom(b);
		assertTrue(map.size() > 0);
		assertEquals("http://127.0.0.1:9010/test.service", ((Map) map.get("services")).get("test.service"));

		Node node1 = new Node();
		Node node0 = new Node();
		node0.value = "0";
		node0.next = node1;
		node1.value = "1";
		node1.prev = node0;
		// write.
		Builder<Node> nodebuilder = Builder.register(Node.class);
		os = new UnsafeByteArrayOutputStream();
		nodebuilder.writeTo(node0, os);
		b = os.toByteArray();
		System.out.println("Node:"+b.length+":"+Bytes.bytes2hex(b));
		// parse
		node0 = nodebuilder.parseFrom(b);
		assertEquals(node0, node0.prev);
		assertEquals(node0, node0.next.prev);
		assertEquals(node0.value, "0");
	}
    public static void main(String[] args) {
        System.out.println(Modifier.isPublic(String.class.getModifiers()));
    }
    @Test
	public void testWithFC() throws Exception
	{
		Builder<SimpleDO> builder = Builder.register(SimpleDO.class);
		UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream();

		SimpleDO sd = new SimpleDO();
		sd.a = 1;
		sd.b = 2;
		sd.c = 3;
		sd.str1 = "12345";
		sd.str2 = "54321";
		builder.writeTo(sd, os);
		byte[] b = os.toByteArray();
		System.out.println(b.length+":"+Bytes.bytes2hex(b));

		sd = builder.parseFrom(b);
		assertEquals(sd.a, 1);
		assertEquals(sd.b, 2);
		assertEquals(sd.c, 3);
		assertEquals(sd.str1, "124");
		System.out.println(sd.str2);
	}

	public enum Type
	{
		Lower, Normal, High;
	}

	static interface TestDO
	{
		String getName();
		void setName(String name);
		Type getType();
		void setType(Type t);
		int getArg();
		void setArg(int arg);
	}

	static class TestDOImpl implements TestDO, Serializable
	{
	    private static final long serialVersionUID = 1L;
		public String getName()
		{
			return "name";
		}
		public void setName(String name){}
		public Type getType()
		{
			return Type.High;
		}
		public void setType(Type t){}
		public int getArg()
		{
			return 28;
		}
		public void setArg(int arg){}
	}

	static class Bean implements Serializable
	{
	    private static final long serialVersionUID = 1L;
		public int vi = 0;
		public long vl = 100l;

		boolean b = true;
		boolean[] bs = {false, true};

		String s1 = "1234567890";
		String s2 = "1234567890一二三四五六七八九零";

		private int i = 123123, ni = -12344, is[] = {1,2,3,4,-1,-2,-3,-4};
        private short s = 12, ns = -76;
		private double d = 12.345, nd = -12.345;
		private long l = 1281447759383l, nl = -13445l;

		private Boolean B = Boolean.FALSE;
		private Integer I = -1234;
		private Double D = new Double(1.23);
		private String name = "qianlei";
		private Type type = Type.Lower, type1 = Type.Normal;
		private Type[] types = { Type.Lower, Type.Lower };

		private Time time = null;

		public Type getType()
		{
			return type;
		}

		public void setType(Type type)
		{
			this.type = type;
		}

		private ArrayList list = new ArrayList();
		{
			list.add(1);
			list.add(2);
			list.add(1308147);
		}
	}

	static class MyList<T> extends ArrayList<T>
	{
		private int code = 12345;
		private String id = "feedback";
	}

	static class MyMap<K, V> extends HashMap<K, V>
	{
		private int code = 12345;
		private String id = "feedback";
	}

	static class Node implements Serializable
	{
        private static final long serialVersionUID = 1L;
        Node prev = this;
		Node next = this;
		String value = "value";

		@Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((value == null) ? 0 : value.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            Node other = (Node) obj;
            if (value == null) {
                if (other.value != null) return false;
            } else if (!value.equals(other.value)) return false;
            return true;
        }
	}

	static class SerializableBean implements Serializable
	{
		private static final long serialVersionUID = -8949681707161463700L;

		public int a = 0;
		public long b = 100l;
		boolean c = true;
		String s1 = "1234567890";
		String s2 = "1234567890一二三四五六七八九零";

		public int hashCode()
		{
			return s1.hashCode() ^ s2.hashCode();
		}

		public boolean equals(Object obj)
		{
			if( obj == null ) return false;
			if( obj == this ) return true;
			if( obj instanceof SerializableBean )
			{
				SerializableBean sb = (SerializableBean)obj;
				return this.a == sb.a && this.b == sb.b && this.c == sb.c && this.s1.equals(sb.s1) && this.s2.equals(sb.s2); 
			}

			return false;
		}
	}
}