package com.jsoniter;

import com.jsoniter.spi.Decoder;
import com.jsoniter.spi.JsoniterSpi;
import com.jsoniter.spi.TypeLiteral;
import junit.framework.TestCase;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class TestSpiTypeDecoder extends TestCase {

    static {
//        JsonIterator.setMode(DecodingMode.DYNAMIC_MODE_AND_MATCH_FIELD_WITH_HASH);
    }

    public static class TestObject1 {
        public int field1;
    }

    public void test_TypeDecoder() throws IOException {
        JsoniterSpi.registerTypeDecoder(TestObject1.class, new Decoder() {
            @Override
            public Object decode(JsonIterator iter) throws IOException {
                iter.skip();
                TestObject1 obj = new TestObject1();
                obj.field1 = 101;
                return obj;
            }
        });
        TestObject1 obj = JsonIterator.deserialize(
                "{'field1': 100}".replace('\'', '"'), TestObject1.class);
        assertEquals(101, obj.field1);
    }

    public void test_TypeDecoder_for_generics() throws IOException {
        TypeLiteral<List<TestObject1>> typeLiteral = new TypeLiteral<List<TestObject1>>() {
        };
        JsoniterSpi.registerTypeDecoder(typeLiteral, new Decoder() {
            @Override
            public Object decode(JsonIterator iter) throws IOException {
                iter.skip();
                TestObject1 obj = new TestObject1();
                obj.field1 = 101;
                return Arrays.asList(obj);
            }
        });
        List<TestObject1> objs = JsonIterator.deserialize(
                "{'field1': 100}".replace('\'', '"'), typeLiteral);
        assertEquals(101, objs.get(0).field1);
    }

    public static class MyDate {
        Date date;
    }

    static {
        JsoniterSpi.registerTypeDecoder(MyDate.class, new Decoder() {
            @Override
            public Object decode(final JsonIterator iter) throws IOException {
                return new MyDate() {{
                    date = new Date(iter.readLong());
                }};
            }
        });
    }

    public void test_direct() throws IOException {
        JsonIterator iter = JsonIterator.parse("1481365190000");
        MyDate date = iter.read(MyDate.class);
        assertEquals(1481365190000L, date.date.getTime());
    }

    public static class FieldWithMyDate {
        public MyDate field;
    }

    public void test_as_field_type() throws IOException {
        JsonIterator iter = JsonIterator.parse("{'field': 1481365190000}".replace('\'', '"'));
        FieldWithMyDate obj = iter.read(FieldWithMyDate.class);
        assertEquals(1481365190000L, obj.field.date.getTime());
    }

    public void test_as_array_element() throws IOException {
        JsonIterator iter = JsonIterator.parse("[1481365190000]");
        MyDate[] dates = iter.read(MyDate[].class);
        assertEquals(1481365190000L, dates[0].date.getTime());
    }
}

@@ -49,16 +49,55 @@
 ecoder;%0A
+import com.jsoniter.spi.JsonException;%0A
 import c
@@ -220,24 +220,52 @@
 OException;%0A
+import java.util.ArrayList;%0A
 import java.
@@ -3055,11 +3055,1330 @@
 );%0A    %7D
+%0A%0A    public static class MyList %7B%0A        public List%3CString%3E list;%0A    %7D%0A%0A    public void test_list_or_single_element() %7B%0A        final TypeLiteral%3CList%3CString%3E%3E listOfString = new TypeLiteral%3CList%3CString%3E%3E() %7B%0A        %7D;%0A        JsoniterSpi.registerTypeDecoder(MyList.class, new Decoder() %7B%0A            @Override%0A            public Object decode(JsonIterator iter) throws IOException %7B%0A                ValueType valueType = iter.whatIsNext();%0A                MyList myList = new MyList();%0A                switch (valueType) %7B%0A                    case ARRAY:%0A                        myList.list = iter.read(listOfString);%0A                        return myList;%0A                    case STRING:%0A                        myList.list = new ArrayList%3CString%3E();%0A                        myList.list.add(iter.readString());%0A                        return myList;%0A                    default:%0A                        throw new JsonException(%22unexpected input%22);%0A                %7D%0A            %7D%0A        %7D);%0A        MyList list1 = JsonIterator.deserialize(%22%5C%22hello%5C%22%22, MyList.class);%0A        assertEquals(%22hello%22, list1.list.get(0));%0A        MyList list2 = JsonIterator.deserialize(%22%5B%5C%22hello%5C%22,%5C%22world%5C%22%5D%22, MyList.class);%0A        assertEquals(%22hello%22, list2.list.get(0));%0A        assertEquals(%22world%22, list2.list.get(1));%0A    %7D
 %0A%7D%0A

add demo of type decoder