import java.io.*;

import org.codehaus.jackson.*;
import org.codehaus.jackson.io.IOContext;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.smile.SmileFactory;
import org.codehaus.jackson.util.BufferRecycler;

// json.org's reference implementation
import org.json.*;
// Jsontool implementation
import com.sdicons.json.parser.JSONParser;
// Noggit:
//import org.apache.noggit.JSONParser;

@SuppressWarnings("unused")
public final class TestJsonPerf
{
    private final int REPS;

    private final static int TEST_PER_GC = 15;

    final JsonFactory _jsonFactory;
    
    final ObjectMapper _mapper;

    final ObjectMapper _smileMapper;
    
    final SmileFactory _smileFactory;
    
    final byte[] _jsonData;

    final byte[] _smileData;
    
    protected int mBatchSize;

    public TestJsonPerf(File f) throws IOException
    {
        _jsonFactory = new JsonFactory();
        _mapper = new ObjectMapper(_jsonFactory);
        _smileFactory = new SmileFactory();
        _smileMapper = new ObjectMapper(_smileFactory);
        _jsonData = readData(f);
        _smileData = convertToSmile(_jsonData);

        // Let's try to guestimate suitable size... to get to 50 megs parsed
        REPS = (int) ((double) (50 * 1000 * 1000) / (double) _jsonData.length);

        System.out.println("Read "+_jsonData.length+" bytes (smile: "+_smileData.length+") from '"+f+"'; will do "+REPS+" reps");
        System.out.println();
    }

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

        while (true) {
            try {  Thread.sleep(100L); } catch (InterruptedException ie) { }
            // Use 9 to test all...
            int round = (i++ % 2);

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

            switch (round) {

            case 0:
                msg = "Smile/data-bind";
                sum += testJacksonDatabind(_smileMapper, _smileData, REPS);
                break;

            case 1:
                msg = "Jackson/data-bind";
                sum += testJacksonDatabind(_mapper, _jsonData, REPS);
                break;
                
            /*
            case 0:
                msg = "Jackson/smile, stream";
                sum += testJacksonStream(REPS, _smileFactory, _smileData, true);
                break;
            case 1:
                msg = "Jackson, stream/byte";
                sum += testJacksonStream(REPS, _jsonFactory, _jsonData, true);
                break;
            case 2:
                msg = "Jackson, stream/char";
                sum += testJacksonStream(REPS, _jsonFactory, _jsonData, false);
                break;

            case 3:
                msg = "Jackson, Java types";
                sum += testJacksonDatabind(_mapper, REPS);
                break;

            case 4:
                msg = "Jackson, JSON types";
                sum += testJacksonJsonTypes(_mapper, REPS);
                break;

            case 5:
                msg = "Noggit";
                sum += testNoggit(REPS);
                break;

            case 6:
                msg = "Json.org";
                sum += testJsonOrg(REPS);
                break;
            case 7:
                msg = "Json-simple";
                sum += testJsonSimple(REPS);
                break;
            case 8:
                msg = "JSONTools (berlios.de)";
                sum += testJsonTools(REPS);
                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)+").");


            if ((i % TEST_PER_GC) == 0) {
                System.out.println("[GC]");
                try {  Thread.sleep(100L); } catch (InterruptedException ie) { }
                System.gc();
                try {  Thread.sleep(100L); } catch (InterruptedException ie) { }
            }
        }
    }

    private final byte[] readData(File f)
        throws IOException
    {
        int len = (int) f.length();
        byte[] data = new byte[len];
        int offset = 0;
        FileInputStream fis = new FileInputStream(f);
        
        while (len > 0) {
            int count = fis.read(data, offset, len-offset);
            offset += count;
            len -= count;
        }

        return data;
    }

    private byte[] convertToSmile(byte[] json) throws IOException
    {
    	JsonParser jp = _jsonFactory.createJsonParser(json);
    	ByteArrayOutputStream out = new ByteArrayOutputStream(200);
        System.out.println("Converting and verifying Smile data...");
    	JsonGenerator jg = _smileFactory.createJsonGenerator(out);
    	while (jp.nextToken() != null) {
    	    jg.copyCurrentEvent(jp);
    	}
    	jp.close();
    	jg.close();
    	byte[] smileBytes = out.toByteArray();
    	System.out.println("Written as "+smileBytes.length+" Smile bytes from "+json.length+" JSON bytes; will verify correctness");

    	// One more thing: let's actually verify correctness!
    	JsonParser sp = _smileFactory.createJsonParser(new ByteArrayInputStream(smileBytes));
        jp = _jsonFactory.createJsonParser(json);
        while (true) {
            JsonToken t1 = jp.nextToken();
            JsonToken t2;
            try {
                t2 = sp.nextToken();
            } catch (IOException ioe) {
                System.err.println("WARN: problem for token matching input token "+t1+" at "+jp.getCurrentLocation());
                throw ioe;
            }
            if (t1 != t2) {
                throw new IllegalArgumentException("Error: tokens differ (json: "+t1+", smile "+t2+") at "+jp.getCurrentLocation());
            }
            if (t1 == null) break;
            if (t1.isScalarValue() || t1 == JsonToken.FIELD_NAME) {
                String str1 = jp.getText();
                String str2 = jp.getText();
                if (str1 == null) {
                    throw new IllegalArgumentException("Error: token texts differ (json: null, smile '"+str2+"') at "+jp.getCurrentLocation());                    
                } else if (!str1.equals(str2)) {
                    throw new IllegalArgumentException("Error: token texts differ (json: '"+str1+"', smile '"+str2+"') at "+jp.getCurrentLocation());                    
                }
            }
        }
        System.out.println("Verified Smile data ("+smileBytes.length+"): same as JSON ("+json.length+")");
    	return smileBytes;
    }
    
    protected int testJsonOrg(int reps)
        throws Exception
    {
        Object ob = null;
        // Json.org's code only accepts Strings:
        String input = new String(_jsonData, "UTF-8");
        for (int i = 0; i < reps; ++i) {
            JSONTokener tok = new JSONTokener(input);
            ob = tok.nextValue();
        }
        return ob.hashCode();
    }

    private int testJsonTools(int reps)
        throws Exception
    {
        Object ob = null;
        for (int i = 0; i < reps; ++i) {
            // Json-tools accepts streams, yay!
            JSONParser jp = new JSONParser(new ByteArrayInputStream(_jsonData), "byte stream");
            /* Hmmmh. Will we get just one object for the whole thing?
             * Or a stream? Seems like just one
             */
            //while ((ob = jp.nextValue()) != null) { ; }
            ob = jp.nextValue();
        }
        return ob.hashCode();
    }

    private int testJsonSimple(int reps)
        throws Exception
    {
        // Json.org's code only accepts Strings:
        String input = new String(_jsonData, "UTF-8");
        Object ob = null;
        for (int i = 0; i < reps; ++i) {
            ob = org.json.simple.JSONValue.parse(input);
        }
        return ob.hashCode();
    }

    private int testNoggit(int reps)
        throws Exception
    {
        ByteArrayInputStream bin = new ByteArrayInputStream(_jsonData);

        char[] cbuf = new char[_jsonData.length];

        IOContext ctxt = new IOContext(new BufferRecycler(), this, false);
        int sum = 0;

        for (int i = 0; i < reps; ++i) {
            /* This may be unfair advantage (allocating buffer of exact
             * size)? But let's do that for now
             */
            //char[] cbuf = new char[mData.length];
            //InputStreamReader r = new InputStreamReader(bin, "UTF-8");
            byte[] bbuf = ctxt.allocReadIOBuffer();
            /* 13-Jan-2009, tatu: Note: Noggit doesn't use our turbo-charged
             *   UTF8 codec by default. But let's make it as fast as we
             *   possibly can...
             */
            UTF8Reader r = new UTF8Reader(ctxt, bin, bbuf, 0, 0);

            bin.reset();
            org.apache.noggit.JSONParser jp = new org.apache.noggit.JSONParser(r, cbuf);
            int type;
            while ((type = jp.nextEvent()) != org.apache.noggit.JSONParser.EOF) {
                if (type == org.apache.noggit.JSONParser.STRING) {
                    sum += jp.getString().length();
                }
            }
        }
        return sum;
    }

    private int testJacksonStream(int reps, JsonFactory factory, byte[] data, boolean fast)
        throws Exception
    {
        int sum = 0;
        for (int i = 0; i < reps; ++i) {
            // note: fast is not used any more
            JsonParser jp;

            if (fast) {
                jp = factory.createJsonParser(data, 0, data.length);
            } else {
                jp = factory.createJsonParser(new ByteArrayInputStream(data));
            }
            JsonToken t;
            while ((t = jp.nextToken()) != null) {
/*                
if (t == JsonToken.FIELD_NAME) System.err.println("'"+jp.getCurrentName()+"'");               
else System.err.println(""+t);                
*/
                // Field names are always constructed
                if (t == JsonToken.VALUE_STRING
                    //|| t == JsonToken.FIELD_NAME
                    ) {
                    sum += jp.getText().length();
                }
            }
            jp.close();
        }
        return sum;
    }

    private int testJacksonDatabind(ObjectMapper mapper, byte[] data, int reps)
        throws Exception
    {
        Object ob = null;
        for (int i = 0; i < reps; ++i) {
            // This is "untyped"... Maps, Lists etc
            ob = mapper.readValue(data, 0, data.length, Object.class);
        }
        return ob.hashCode(); // just to get some non-optimizable number
    }

    private int testJacksonTree(ObjectMapper mapper, byte[] data, int reps)
        throws Exception
    {
        Object ob = null;
        for (int i = 0; i < reps; ++i) {
            ob = mapper.readValue(data, 0, data.length, JsonNode.class);
        }
        return ob.hashCode(); // just to get some non-optimizable number
    }

    public static void main(String[] args)
        throws Exception
    {
        if (args.length != 1) {
            System.err.println("Usage: java ... <file>");
            System.exit(1);
        }
        new TestJsonPerf(new File(args[0])).test();
    }
}

