/*
 * Copyright (C) 2011 Google Inc.
 *
 * 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 benchmarks.regression;

import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
import org.xmlpull.v1.XmlPullParser;

/**
 * Measure throughput of various parsers.
 *
 * <p>This benchmark requires that ParseBenchmarkData.zip is on the classpath.
 * That file contains Twitter feed data, which is representative of what
 * applications will be parsing.
 */
public final class ParseBenchmark extends SimpleBenchmark {

    @Param Document document;
    @Param Api api;

    private enum Document {
        TWEETS,
        READER_SHORT,
        READER_LONG
    }

    private enum Api {
        ANDROID_STREAM("json") {
            @Override Parser newParser() {
                return new AndroidStreamParser();
            }
        },
        ORG_JSON("json") {
            @Override Parser newParser() {
                return new OrgJsonParser();
            }
        },
        XML_PULL("xml") {
            @Override Parser newParser() {
                return new GeneralXmlPullParser();
            }
        },
        XML_DOM("xml") {
            @Override Parser newParser() {
                return new XmlDomParser();
            }
        },
        XML_SAX("xml") {
            @Override Parser newParser() {
                return new XmlSaxParser();
            }
        };

        final String extension;

        private Api(String extension) {
            this.extension = extension;
        }

        abstract Parser newParser();
    }

    private String text;
    private Parser parser;

    @Override protected void setUp() throws Exception {
        text = resourceToString("/" + document.name() + "." + api.extension);
        parser = api.newParser();
    }

    public void timeParse(int reps) throws Exception {
        for (int i = 0; i < reps; i++) {
            parser.parse(text);
        }
    }

    public static void main(String... args) throws Exception {
        Runner.main(ParseBenchmark.class, args);
    }

    private static String resourceToString(String path) throws Exception {
        InputStream in = ParseBenchmark.class.getResourceAsStream(path);
        if (in == null) {
            throw new IllegalArgumentException("No such file: " + path);
        }

        Reader reader = new InputStreamReader(in, "UTF-8");
        char[] buffer = new char[8192];
        StringWriter writer = new StringWriter();
        int count;
        while ((count = reader.read(buffer)) != -1) {
            writer.write(buffer, 0, count);
        }
        reader.close();
        return writer.toString();
    }

    interface Parser {
        void parse(String data) throws Exception;
    }

    private static class AndroidStreamParser implements Parser {
        @Override public void parse(String data) throws Exception {
            android.util.JsonReader jsonReader
                    = new android.util.JsonReader(new StringReader(data));
            readToken(jsonReader);
            jsonReader.close();
        }

        public void readObject(android.util.JsonReader reader) throws IOException {
            reader.beginObject();
            while (reader.hasNext()) {
                reader.nextName();
                readToken(reader);
            }
            reader.endObject();
        }

        public void readArray(android.util.JsonReader reader) throws IOException {
            reader.beginArray();
            while (reader.hasNext()) {
                readToken(reader);
            }
            reader.endArray();
        }

        private void readToken(android.util.JsonReader reader) throws IOException {
            switch (reader.peek()) {
            case BEGIN_ARRAY:
                readArray(reader);
                break;
            case BEGIN_OBJECT:
                readObject(reader);
                break;
            case BOOLEAN:
                reader.nextBoolean();
                break;
            case NULL:
                reader.nextNull();
                break;
            case NUMBER:
                reader.nextLong();
                break;
            case STRING:
                reader.nextString();
                break;
            default:
                throw new IllegalArgumentException("Unexpected token" + reader.peek());
            }
        }
    }

    private static class OrgJsonParser implements Parser {
        @Override public void parse(String data) throws Exception {
            if (data.startsWith("[")) {
                new JSONArray(data);
            } else if (data.startsWith("{")) {
                new JSONObject(data);
            } else {
                throw new IllegalArgumentException();
            }
        }
    }

    private static class GeneralXmlPullParser implements Parser {
        @Override public void parse(String data) throws Exception {
            XmlPullParser xmlParser = android.util.Xml.newPullParser();
            xmlParser.setInput(new StringReader(data));
            xmlParser.nextTag();
            while (xmlParser.next() != XmlPullParser.END_DOCUMENT) {
                xmlParser.getName();
                xmlParser.getText();
            }
        }
    }

    private static class XmlDomParser implements Parser {
        @Override public void parse(String data) throws Exception {
            DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .parse(new InputSource(new StringReader(data)));
        }
    }

    private static class XmlSaxParser implements Parser {
        @Override public void parse(String data) throws Exception {
            SAXParserFactory.newInstance().newSAXParser().parse(
                    new InputSource(new StringReader(data)), new DefaultHandler());
        }
    }
}
