/*
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.parser;

import java.util.ArrayList;
import java.util.List;
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ECMAErrors;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSErrorType;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.SpillProperty;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.scripts.JO;

import static jdk.nashorn.internal.parser.TokenType.STRING;

/**
 * Parses JSON text and returns the corresponding IR node. This is derived from the objectLiteral production of the main parser.
 *
 * See: 15.12.1.2 The JSON Syntactic Grammar
 */
public class JSONParser {

    final private String source;
    final private Global global;
    final int length;
    int pos = 0;

    private static PropertyMap EMPTY_MAP = PropertyMap.newMap();

    private static final int EOF = -1;

    private static final String TRUE  = "true";
    private static final String FALSE = "false";
    private static final String NULL  = "null";

    private static final int STATE_EMPTY          = 0;
    private static final int STATE_ELEMENT_PARSED = 1;
    private static final int STATE_COMMA_PARSED   = 2;

    /**
     * Constructor
     * @param source  the source
     * @param global the global object
     */
    public JSONParser(final String source, final Global global ) {
        this.source = source;
        this.global = global;
        this.length = source.length();
    }

    /**
     * Implementation of the Quote(value) operation as defined in the ECMA script spec
     * It wraps a String value in double quotes and escapes characters within in
     *
     * @param value string to quote
     *
     * @return quoted and escaped string
     */
    public static String quote(final String value) {

        final StringBuilder product = new StringBuilder();

        product.append("\"");

        for (final char ch : value.toCharArray()) {
            // TODO: should use a table?
            switch (ch) {
            case '\\':
                product.append("\\\\");
                break;
            case '"':
                product.append("\\\"");
                break;
            case '\b':
                product.append("\\b");
                break;
            case '\f':
                product.append("\\f");
                break;
            case '\n':
                product.append("\\n");
                break;
            case '\r':
                product.append("\\r");
                break;
            case '\t':
                product.append("\\t");
                break;
            default:
                if (ch < ' ') {
                    product.append(Lexer.unicodeEscape(ch));
                    break;
                }

                product.append(ch);
                break;
            }
        }

        product.append("\"");

        return product.toString();
    }

    /**
     * Public parse method. Parse a string into a JSON object.
     *
     * @return the parsed JSON Object
     */
    public Object parse() {
        final Object value = parseLiteral();
        skipWhiteSpace();
        if (pos < length) {
            throw expectedError(pos, "eof", toString(peek()));
        }
        return value;
    }

    private Object parseLiteral() {
        skipWhiteSpace();

        final int c = peek();
        if (c == EOF) {
            throw expectedError(pos, "json literal", "eof");
        }
        switch (c) {
        case '{':
            return parseObject();
        case '[':
            return parseArray();
        case '"':
            return parseString();
        case 'f':
            return parseKeyword(FALSE, Boolean.FALSE);
        case 't':
            return parseKeyword(TRUE, Boolean.TRUE);
        case 'n':
            return parseKeyword(NULL, null);
        default:
            if (isDigit(c) || c == '-') {
                return parseNumber();
            } else if (c == '.') {
                throw numberError(pos);
            } else {
                throw expectedError(pos, "json literal", toString(c));
            }
        }
    }

    private Object parseObject() {
        PropertyMap propertyMap = EMPTY_MAP;
        ArrayData arrayData = ArrayData.EMPTY_ARRAY;
        final ArrayList<Object> values = new ArrayList<>();
        int state = STATE_EMPTY;

        assert peek() == '{';
        pos++;

        while (pos < length) {
            skipWhiteSpace();
            final int c = peek();

            switch (c) {
            case '"':
                if (state == STATE_ELEMENT_PARSED) {
                    throw expectedError(pos - 1, ", or }", toString(c));
                }
                final String id = parseString();
                expectColon();
                final Object value = parseLiteral();
                final int index = ArrayIndex.getArrayIndex(id);
                if (ArrayIndex.isValidArrayIndex(index)) {
                    arrayData = addArrayElement(arrayData, index, value);
                } else {
                    propertyMap = addObjectProperty(propertyMap, values, id, value);
                }
                state = STATE_ELEMENT_PARSED;
                break;
            case ',':
                if (state != STATE_ELEMENT_PARSED) {
                    throw error(AbstractParser.message("trailing.comma.in.json"), pos);
                }
                state = STATE_COMMA_PARSED;
                pos++;
                break;
            case '}':
                if (state == STATE_COMMA_PARSED) {
                    throw error(AbstractParser.message("trailing.comma.in.json"), pos);
                }
                pos++;
                return createObject(propertyMap, values, arrayData);
            default:
                throw expectedError(pos, ", or }", toString(c));
            }
        }
        throw expectedError(pos, ", or }", "eof");
    }

    private static ArrayData addArrayElement(final ArrayData arrayData, final int index, final Object value) {
        final long oldLength = arrayData.length();
        final long longIndex = ArrayIndex.toLongIndex(index);
        ArrayData newArrayData = arrayData;
        if (longIndex >= oldLength) {
            newArrayData = newArrayData.ensure(longIndex);
            if (longIndex > oldLength) {
                newArrayData = newArrayData.delete(oldLength, longIndex - 1);
            }
        }
        return newArrayData.set(index, value, false);
    }

    private static PropertyMap addObjectProperty(final PropertyMap propertyMap, final List<Object> values,
                                                 final String id, final Object value) {
        final Property oldProperty = propertyMap.findProperty(id);
        final Property newProperty;
        final PropertyMap newMap;
        final Class<?> type = ObjectClassGenerator.OBJECT_FIELDS_ONLY ? Object.class : getType(value);

        if (oldProperty != null) {
            values.set(oldProperty.getSlot(), value);
            newProperty = new SpillProperty(id, 0, oldProperty.getSlot());
            newProperty.setType(type);
            newMap = propertyMap.replaceProperty(oldProperty, newProperty);;
        } else {
            values.add(value);
            newProperty = new SpillProperty(id, 0, propertyMap.size());
            newProperty.setType(type);
            newMap = propertyMap.addProperty(newProperty);
        }

        return newMap;
    }

    private Object createObject(final PropertyMap propertyMap, final List<Object> values, final ArrayData arrayData) {
        final long[] primitiveSpill = new long[values.size()];
        final Object[] objectSpill = new Object[values.size()];

        for (final Property property : propertyMap.getProperties()) {
            if (property.getType() == Object.class) {
                objectSpill[property.getSlot()] = values.get(property.getSlot());
            } else {
                primitiveSpill[property.getSlot()] = ObjectClassGenerator.pack((Number) values.get(property.getSlot()));
            }
        }

        final ScriptObject object = new JO(propertyMap, primitiveSpill, objectSpill);
        object.setInitialProto(global.getObjectPrototype());
        object.setArray(arrayData);
        return object;
    }

    private static Class<?> getType(final Object value) {
        if (value instanceof Integer) {
            return int.class;
        } else if (value instanceof Long) {
            return long.class;
        } else if (value instanceof Double) {
            return double.class;
        } else {
            return Object.class;
        }
    }

    private void expectColon() {
        skipWhiteSpace();
        final int n = next();
        if (n != ':') {
            throw expectedError(pos - 1, ":", toString(n));
        }
    }

    private Object parseArray() {
        ArrayData arrayData = ArrayData.EMPTY_ARRAY;
        int state = STATE_EMPTY;

        assert peek() == '[';
        pos++;

        while (pos < length) {
            skipWhiteSpace();
            final int c = peek();

            switch (c) {
            case ',':
                if (state != STATE_ELEMENT_PARSED) {
                    throw error(AbstractParser.message("trailing.comma.in.json"), pos);
                }
                state = STATE_COMMA_PARSED;
                pos++;
                break;
            case ']':
                if (state == STATE_COMMA_PARSED) {
                    throw error(AbstractParser.message("trailing.comma.in.json"), pos);
                }
                pos++;
                return global.wrapAsObject(arrayData);
            default:
                if (state == STATE_ELEMENT_PARSED) {
                    throw expectedError(pos, ", or ]", toString(c));
                }
                final long index = arrayData.length();
                arrayData = arrayData.ensure(index).set((int) index, parseLiteral(), true);
                state = STATE_ELEMENT_PARSED;
                break;
            }
        }

        throw expectedError(pos, ", or ]", "eof");
    }

    private String parseString() {
        // String buffer is only instantiated if string contains escape sequences.
        int start = ++pos;
        StringBuilder sb = null;

        while (pos < length) {
            final int c = next();
            if (c <= 0x1f) {
                // Characters < 0x1f are not allowed in JSON strings.
                throw syntaxError(pos, "String contains control character");

            } else if (c == '\\') {
                if (sb == null) {
                    sb = new StringBuilder(pos - start + 16);
                }
                sb.append(source, start, pos - 1);
                sb.append(parseEscapeSequence());
                start = pos;

            } else if (c == '"') {
                if (sb != null) {
                    sb.append(source, start, pos - 1);
                    return sb.toString();
                }
                return source.substring(start, pos - 1);
            }
        }

        throw error(Lexer.message("missing.close.quote"), pos, length);
    }

    private char parseEscapeSequence() {
        final int c = next();
        switch (c) {
        case '"':
            return '"';
        case '\\':
            return '\\';
        case '/':
            return '/';
        case 'b':
            return '\b';
        case 'f':
            return '\f';
        case 'n':
            return '\n';
        case 'r':
            return '\r';
        case 't':
            return '\t';
        case 'u':
            return parseUnicodeEscape();
        default:
            throw error(Lexer.message("invalid.escape.char"), pos - 1, length);
        }
    }

    private char parseUnicodeEscape() {
        return (char) (parseHexDigit() << 12 | parseHexDigit() << 8 | parseHexDigit() << 4 | parseHexDigit());
    }

    private int parseHexDigit() {
        final int c = next();
        if (c >= '0' && c <= '9') {
            return c - '0';
        } else if (c >= 'A' && c <= 'F') {
            return c + 10 - 'A';
        } else if (c >= 'a' && c <= 'f') {
            return c + 10 - 'a';
        }
        throw error(Lexer.message("invalid.hex"), pos - 1, length);
    }

    private boolean isDigit(final int c) {
        return c >= '0' && c <= '9';
    }

    private void skipDigits() {
        while (pos < length) {
            final int c = peek();
            if (!isDigit(c)) {
                break;
            }
            pos++;
        }
    }

    private Number parseNumber() {
        final int start = pos;
        int c = next();

        if (c == '-') {
            c = next();
        }
        if (!isDigit(c)) {
            throw numberError(start);
        }
        // no more digits allowed after 0
        if (c != '0') {
            skipDigits();
        }

        // fraction
        if (peek() == '.') {
            pos++;
            if (!isDigit(next())) {
                throw numberError(pos - 1);
            }
            skipDigits();
        }

        // exponent
        c = peek();
        if (c == 'e' || c == 'E') {
            pos++;
            c = next();
            if (c == '-' || c == '+') {
                c = next();
            }
            if (!isDigit(c)) {
                throw numberError(pos - 1);
            }
            skipDigits();
        }

        final double d = Double.parseDouble(source.substring(start, pos));
        if (JSType.isRepresentableAsInt(d)) {
            return (int) d;
        } else if (JSType.isRepresentableAsLong(d)) {
            return (long) d;
        }
        return d;
    }

    private Object parseKeyword(final String keyword, final Object value) {
        if (!source.regionMatches(pos, keyword, 0, keyword.length())) {
            throw expectedError(pos, "json literal", "ident");
        }
        pos += keyword.length();
        return value;
    }

    private int peek() {
        if (pos >= length) {
            return -1;
        }
        return source.charAt(pos);
    }

    private int next() {
        final int next = peek();
        pos++;
        return next;
    }

    private void skipWhiteSpace() {
        while (pos < length) {
            switch (peek()) {
            case '\t':
            case '\r':
            case '\n':
            case ' ':
                pos++;
                break;
            default:
                return;
            }
        }
    }

    private static String toString(final int c) {
        return c == EOF ? "eof" : String.valueOf((char) c);
    }

    ParserException error(final String message, final int start, final int length) throws ParserException {
        final long token     = Token.toDesc(STRING, start, length);
        final int  pos       = Token.descPosition(token);
        final Source src     = Source.sourceFor("<json>", source);
        final int  lineNum   = src.getLine(pos);
        final int  columnNum = src.getColumn(pos);
        final String formatted = ErrorManager.format(message, src, lineNum, columnNum, token);
        return new ParserException(JSErrorType.SYNTAX_ERROR, formatted, src, lineNum, columnNum, token);
    }

    private ParserException error(final String message, final int start) {
        return error(message, start, length);
    }

    private ParserException numberError(final int start) {
        return error(Lexer.message("json.invalid.number"), start);
    }

    private ParserException expectedError(final int start, final String expected, final String found) {
        return error(AbstractParser.message("expected", expected, found), start);
    }

    private ParserException syntaxError(final int start, final String reason) {
        final String message = ECMAErrors.getMessage("syntax.error.invalid.json", reason);
        return error(message, start);
    }
}
