/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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 org.json;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;

public class ParsingTest extends TestCase {

    public void testParsingNoObjects() {
        try {
            new JSONTokener("").nextValue();
            fail();
        } catch (JSONException e) {
        }
    }

    public void testParsingLiterals() throws JSONException {
        assertParsed(Boolean.TRUE, "true");
        assertParsed(Boolean.FALSE, "false");
        assertParsed(JSONObject.NULL, "null");
        assertParsed(JSONObject.NULL, "NULL");
        assertParsed(Boolean.FALSE, "False");
        assertParsed(Boolean.TRUE, "truE");
    }

    public void testParsingQuotedStrings() throws JSONException {
        assertParsed("abc", "\"abc\"");
        assertParsed("123", "\"123\"");
        assertParsed("foo\nbar", "\"foo\\nbar\"");
        assertParsed("foo bar", "\"foo\\u0020bar\"");
        assertParsed("\"{}[]/\\:,=;#", "\"\\\"{}[]/\\\\:,=;#\"");
    }

    public void testParsingSingleQuotedStrings() throws JSONException {
        assertParsed("abc", "'abc'");
        assertParsed("123", "'123'");
        assertParsed("foo\nbar", "'foo\\nbar'");
        assertParsed("foo bar", "'foo\\u0020bar'");
        assertParsed("\"{}[]/\\:,=;#", "'\\\"{}[]/\\\\:,=;#'");
    }

    public void testParsingUnquotedStrings() throws JSONException {
        assertParsed("abc", "abc");
        assertParsed("123abc", "123abc");
        assertParsed("123e0x", "123e0x");
        assertParsed("123e", "123e");
        assertParsed("123ee21", "123ee21");
        assertParsed("0xFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFF");
    }

    /**
     * Unfortunately the original implementation attempts to figure out what
     * Java number type best suits an input value.
     */
    public void testParsingNumbersThatAreBestRepresentedAsLongs() throws JSONException {
        assertParsed(9223372036854775807L, "9223372036854775807");
        assertParsed(9223372036854775806L, "9223372036854775806");
        assertParsed(-9223372036854775808L, "-9223372036854775808");
        assertParsed(-9223372036854775807L, "-9223372036854775807");
    }

    public void testParsingNumbersThatAreBestRepresentedAsIntegers() throws JSONException {
        assertParsed(0, "0");
        assertParsed(5, "5");
        assertParsed(-2147483648, "-2147483648");
        assertParsed(2147483647, "2147483647");
    }

    public void testParsingNegativeZero() throws JSONException {
        assertParsed(0, "-0");
    }

    public void testParsingIntegersWithAdditionalPrecisionYieldDoubles() throws JSONException {
        assertParsed(1d, "1.00");
        assertParsed(1d, "1.0");
        assertParsed(0d, "0.0");
        assertParsed(-0d, "-0.0");
    }

    public void testParsingNumbersThatAreBestRepresentedAsDoubles() throws JSONException {
        assertParsed(9.223372036854776E18, "9223372036854775808");
        assertParsed(-9.223372036854776E18, "-9223372036854775809");
        assertParsed(1.7976931348623157E308, "1.7976931348623157e308");
        assertParsed(2.2250738585072014E-308, "2.2250738585072014E-308");
        assertParsed(4.9E-324, "4.9E-324");
        assertParsed(4.9E-324, "4.9e-324");
    }

    public void testParsingOctalNumbers() throws JSONException {
        assertParsed(5, "05");
        assertParsed(8, "010");
        assertParsed(1046, "02026");
    }

    public void testParsingHexNumbers() throws JSONException {
        assertParsed(5, "0x5");
        assertParsed(16, "0x10");
        assertParsed(8230, "0x2026");
        assertParsed(180150010, "0xABCDEFA");
        assertParsed(2077093803, "0x7BCDEFAB");
    }

    public void testParsingLargeHexValues() throws JSONException {
        assertParsed(Integer.MAX_VALUE, "0x7FFFFFFF");
        String message = "Hex values are parsed as Strings if their signed " +
                "value is greater than Integer.MAX_VALUE.";
        assertParsed(message, 0x80000000L, "0x80000000");
    }

    public void test64BitHexValues() throws JSONException {
        assertParsed("Large hex longs shouldn't be yield ints or strings",
                -1L, "0xFFFFFFFFFFFFFFFF");
    }

    public void testParsingWithCommentsAndWhitespace() throws JSONException {
        assertParsed("baz", "  // foo bar \n baz");
        assertParsed("baz", "  // foo bar \r baz");
        assertParsed("baz", "  // foo bar \r\n baz");
        assertParsed("baz", "  # foo bar \n baz");
        assertParsed("baz", "  # foo bar \r baz");
        assertParsed("baz", "  # foo bar \r\n baz");
        assertParsed(5, "  /* foo bar \n baz */ 5");
        assertParsed(5, "  /* foo bar \n baz */ 5 // quux");
        assertParsed(5, "  5   ");
        assertParsed(5, "  5  \r\n\t ");
        assertParsed(5, "\r\n\t   5 ");
    }

    public void testParsingArrays() throws JSONException {
        assertParsed(array(), "[]");
        assertParsed(array(5, 6, true), "[5,6,true]");
        assertParsed(array(5, 6, array()), "[5,6,[]]");
        assertParsed(array(5, 6, 7), "[5;6;7]");
        assertParsed(array(5, 6, 7), "[5  , 6 \t; \r\n 7\n]");
        assertParsed(array(5, 6, 7, null), "[5,6,7,]");
        assertParsed(array(null, null), "[,]");
        assertParsed(array(5, null, null, null, 5), "[5,,,,5]");
        assertParsed(array(null, 5), "[,5]");
        assertParsed(array(null, null, null), "[,,]");
        assertParsed(array(null, null, null, 5), "[,,,5]");
    }

    public void testParsingObjects() throws JSONException {
        assertParsed(object("foo", 5), "{\"foo\": 5}");
        assertParsed(object("foo", 5), "{foo: 5}");
        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5, \"bar\": \"baz\"}");
        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5; \"bar\": \"baz\"}");
        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"= 5; \"bar\"= \"baz\"}");
        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"=> 5; \"bar\"=> \"baz\"}");
        assertParsed(object("foo", object(), "bar", array()), "{\"foo\"=> {}; \"bar\"=> []}");
        assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\": {\"foo\": [5, 6]}}");
        assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\":\n\t{\t \"foo\":[5,\r6]}}");
    }

    public void testSyntaxProblemUnterminatedObject() {
        assertParseFail("{");
        assertParseFail("{\"foo\"");
        assertParseFail("{\"foo\":");
        assertParseFail("{\"foo\":bar");
        assertParseFail("{\"foo\":bar,");
        assertParseFail("{\"foo\":bar,\"baz\"");
        assertParseFail("{\"foo\":bar,\"baz\":");
        assertParseFail("{\"foo\":bar,\"baz\":true");
        assertParseFail("{\"foo\":bar,\"baz\":true,");
    }

    public void testSyntaxProblemEmptyString() {
        assertParseFail("");
    }

    public void testSyntaxProblemUnterminatedArray() {
        assertParseFail("[");
        assertParseFail("[,");
        assertParseFail("[,,");
        assertParseFail("[true");
        assertParseFail("[true,");
        assertParseFail("[true,,");
    }

    public void testSyntaxProblemMalformedObject() {
        assertParseFail("{:}");
        assertParseFail("{\"key\":}");
        assertParseFail("{:true}");
        assertParseFail("{\"key\":true:}");
        assertParseFail("{null:true}");
        assertParseFail("{true:true}");
        assertParseFail("{0xFF:true}");
    }

    private void assertParseFail(String malformedJson) {
        try {
            new JSONTokener(malformedJson).nextValue();
            fail("Successfully parsed: \"" + malformedJson + "\"");
        } catch (JSONException e) {
        } catch (StackOverflowError e) {
            fail("Stack overflowed on input: \"" + malformedJson + "\"");
        }
    }

    private JSONArray array(Object... elements) {
        return new JSONArray(Arrays.asList(elements));
    }

    private JSONObject object(Object... keyValuePairs) throws JSONException {
        JSONObject result = new JSONObject();
        for (int i = 0; i < keyValuePairs.length; i+=2) {
            result.put((String) keyValuePairs[i], keyValuePairs[i+1]);
        }
        return result;
    }

    private void assertParsed(String message, Object expected, String json) throws JSONException {
        Object actual = new JSONTokener(json).nextValue();
        actual = canonicalize(actual);
        expected = canonicalize(expected);
        assertEquals("For input \"" + json + "\" " + message, expected, actual);
    }

    private void assertParsed(Object expected, String json) throws JSONException {
        assertParsed("", expected, json);
    }

    /**
     * Since they don't implement equals or hashCode properly, this recursively
     * replaces JSONObjects with an equivalent HashMap, and JSONArrays with the
     * equivalent ArrayList.
     */
    private Object canonicalize(Object input) throws JSONException {
        if (input instanceof JSONArray) {
            JSONArray array = (JSONArray) input;
            List<Object> result = new ArrayList<Object>();
            for (int i = 0; i < array.length(); i++) {
                result.add(canonicalize(array.opt(i)));
            }
            return result;
        } else if (input instanceof JSONObject) {
            JSONObject object = (JSONObject) input;
            Map<String, Object> result = new HashMap<String, Object>();
            for (Iterator<?> i = object.keys(); i.hasNext(); ) {
                String key = (String) i.next();
                result.put(key, canonicalize(object.get(key)));
            }
            return result;
        } else {
            return input;
        }
    }
}
