import java.io.*;

import org.codehaus.jackson.annotate.*;
import org.codehaus.jackson.map.*;

/**
 * Micro-benchmark for comparing performance of bean deserialization
 * using method-based method or Creator-based (constructor or
 * factory method)
 */
public final class TestCreatorPerf
{
    /*
    /////////////////////////////////////////////////////
    // Bean classes
    /////////////////////////////////////////////////////
     */

    final static class MethodBean
    {
        int x;
        long y;
        boolean state;

        protected MethodBean() { }

        public void setX(int v) { x = v; }
        public void setY(long v) { y = v; }
        public void setState(boolean v) { state = v; }

        @Override
        public int hashCode() { return x ^ (int) y ^ (state ? 1 : -1); }
    }

    final static class ConstructorBean
    {
        final int x;
        final long y;
        final boolean state;

        @JsonCreator public ConstructorBean(@JsonProperty("x") int a1,
                                            @JsonProperty("y") long a2,
                                            @JsonProperty("state") boolean a4)
        {
            x = a1;
            y = a2;
            state = a4;
        }

        @Override
        public int hashCode() { return x ^ (int) y ^ (state ? 1 : -1); }
    }

    final static class FactoryBean
    {
        int x;
        long y;
        boolean state;

        private FactoryBean() { }

        @JsonCreator public static FactoryBean buildIt(@JsonProperty("x") int a1,
                                                       @JsonProperty("y") long a2,
                                                       @JsonProperty("state") boolean a4)
        {
            FactoryBean bean = new FactoryBean();
            bean.x = a1;
            bean.y = a2;
            bean.state = a4;
            return bean;
        }

        @Override
        public int hashCode() { return x ^ (int) y ^ (state ? 1 : -1); }
    }


    private final int REPS;
    private final ObjectMapper _mapper;
    private final byte[] _data;
    
    public TestCreatorPerf()
        throws Exception
    {
        // Let's try to guestimate suitable size, to spend enough (but not too much) time per round
        REPS = 13000;
        _mapper = new ObjectMapper();
        _data = "{ \"x\" : -15980, \"y\" : 1234567890123, \"state\" : true }".getBytes("UTF-8");
    }

    public void test()
        throws Exception
    {
        int i = 0;
        int sum = 0;

        System.out.println("START: content size "+_data.length+" bytes");
        ByteArrayInputStream in = new ByteArrayInputStream(_data);

        while (true) {
            try {  Thread.sleep(100L); } catch (InterruptedException ie) { }
            int round = (i++ % 3);

            long curr = System.currentTimeMillis();
            String msg;
            boolean lf = (round == 0);

            switch (round) {

            case 0:
                msg = "Jackson, setters";
                sum += testDeser(REPS, in, MethodBean.class);
                break;
            case 1:
                msg = "Jackson, constructor";
                sum += testDeser(REPS, in, ConstructorBean.class);
                break;
            case 2:
                msg = "Jackson, factory";
                sum += testDeser(REPS, in, FactoryBean.class);
                break;
            default:
                throw new Error("Internal error");
            }

            curr = System.currentTimeMillis() - curr;
            if (lf) {
                System.out.println();
            }
            System.out.println("Test '"+msg+"' -> "+curr+" msecs ("
                               +(sum & 0xFF)+").");

        }
    }

    protected <T> int testDeser(int reps, ByteArrayInputStream in, Class<T> beanType)
        throws Exception
    {
        T result = null;
        for (int i = 0; i < reps; ++i) {
            in.reset();
            result = _mapper.readValue(in, beanType);
        }
        return result.hashCode(); // just to get some non-optimizable number
    }

    public static void main(String[] args) throws Exception
    {
        new TestCreatorPerf().test();
    }
}
