/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.felix.dm.runtime;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A very small JSON parser.
 * Code adapted from the org.apache.felix.serializer.impl.json.JsonParser.java, 
 * from the Apache Felix Converter project.
 *
 * The JSON input is parsed into an object structure in the following way:
 * <ul>
 * <li>Object names are represented as a {@link String}.
 * <li>String values are represented as a {@link String}.
 * <li>Numeric values without a decimal separator are represented as a {@link Long}.
 * <li>Numeric values with a decimal separator are represented as a {@link Double}.
 * <li>Boolean values are represented as a {@link Boolean}.
 * <li>Nested JSON objects are parsed into a {@link java.util.Map Map&lt;String, Object&gt;}.
 * <li>JSON lists are parsed into a {@link java.util.List} which may contain any of the above values.
 * </ul>
 */
public class JsonReader {
    private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("^\\s*[\"](.+?)[\"]\\s*[:]\\s*(.+)$");

    private enum Scope { QUOTE, CURLY, BRACKET;
        static Scope getScope(char c) {
            switch (c) {
            case '"':
                return QUOTE;
            case '[':
            case ']':
                return BRACKET;
            case '{':
            case '}':
                return CURLY;
            default:
                return null;
            }
        }
    }

    static class Pair<K, V> {
        final K key;
        final V value;

        Pair(K k, V v) {
            key = k;
            value = v;
        }
    }

    private final Map<String, Object> parsed;

    public JsonReader(CharSequence json) {
        String str = json.toString();
        str = str.trim().replace('\n', ' ');
        parsed = parseObject(str);
    }

    public JsonReader(InputStream is) throws IOException {
        this(readStreamAsString(is));
    }

    public Map<String, Object> getParsed() {
        return parsed;
    }

    private static Pair<String, Object> parseKeyValue(String jsonKeyValue) {
        Matcher matcher = KEY_VALUE_PATTERN.matcher(jsonKeyValue);
        if (!matcher.matches() || matcher.groupCount() < 2) {
            throw new IllegalArgumentException("Malformatted JSON key-value pair: " + jsonKeyValue);
        }

        return new Pair<>(matcher.group(1), parseValue(matcher.group(2)));
    }

    private static Object parseValue(String jsonValue) {
        jsonValue = jsonValue.trim();

        switch (jsonValue.charAt(0)) {
        case '\"':
            if (!jsonValue.endsWith("\""))
                throw new IllegalArgumentException("Malformatted JSON string: " + jsonValue);

            return jsonValue.substring(1, jsonValue.length() - 1);
        case '[':
            List<Object> entries = new ArrayList<>();
            for (String v : parseListValuesRaw(jsonValue)) {
                entries.add(parseValue(v));
            }
            return entries;
        case '{':
            return parseObject(jsonValue);
        case 't':
        case 'T':
        case 'f':
        case 'F':
            return Boolean.parseBoolean(jsonValue);
        case 'n':
        case 'N':
            return null;
        default:
            if (jsonValue.contains(".")) {
                return Double.parseDouble(jsonValue);
            }
            return Long.parseLong(jsonValue);
        }
    }

    private static Map<String, Object> parseObject(String jsonObject) {
        if (!(jsonObject.startsWith("{") && jsonObject.endsWith("}")))
            throw new IllegalArgumentException("Malformatted JSON object: " + jsonObject);

        Map<String, Object> values = new HashMap<>();

        jsonObject = jsonObject.substring(1, jsonObject.length() - 1).trim();
        if (jsonObject.length() == 0)
            return values;

        for (String element : parseKeyValueListRaw(jsonObject)) {
            Pair<String, Object> pair = parseKeyValue(element);
            values.put(pair.key, pair.value);
        }

        return values;
    }

    private static List<String> parseKeyValueListRaw(String jsonKeyValueList) {
        if (jsonKeyValueList.trim().isEmpty())
            return Collections.emptyList();
        jsonKeyValueList = jsonKeyValueList + ","; // append comma to simplify parsing
        List<String> elements = new ArrayList<>();

        int i=0;
        int start=0;
        Stack<Scope> scopeStack = new Stack<>();
        while (i < jsonKeyValueList.length()) {
            char curChar = jsonKeyValueList.charAt(i);
            switch (curChar) {
            case '"':
                if (i > 0 && jsonKeyValueList.charAt(i-1) == '\\') {
                    // it's escaped, ignore for now
                } else {
                    if (!scopeStack.empty() && scopeStack.peek() == Scope.QUOTE) {
                        scopeStack.pop();
                    } else {
                        scopeStack.push(Scope.QUOTE);
                    }
                }
                break;
            case '[':
            case '{':
                if ((scopeStack.empty() ? null : scopeStack.peek()) == Scope.QUOTE) {
                    // inside quotes, ignore
                } else {
                    scopeStack.push(Scope.getScope(curChar));
                }
                break;
            case ']':
            case '}':
                Scope curScope = scopeStack.empty() ? null : scopeStack.peek();
                if (curScope == Scope.QUOTE) {
                    // inside quotes, ignore
                } else {
                    Scope newScope = Scope.getScope(curChar);
                    if (curScope == newScope) {
                        scopeStack.pop();
                    } else {
                        throw new IllegalArgumentException("Unbalanced closing " +
                            curChar + " in: " + jsonKeyValueList);
                    }
                }
                break;
            case ',':
                if (scopeStack.empty()) {
                    elements.add(jsonKeyValueList.substring(start, i));
                    start = i+1;
                }
                break;
            }

            i++;
        }
        return elements;
    }

    private static List<String> parseListValuesRaw(String jsonList) {
        if (!(jsonList.startsWith("[") && jsonList.endsWith("]")))
            throw new IllegalArgumentException("Malformatted JSON list: " + jsonList);

        jsonList = jsonList.substring(1, jsonList.length() - 1);
        return parseKeyValueListRaw(jsonList);
    }

    private static String readStreamAsString(InputStream is) throws IOException {
        byte [] bytes = readStream(is);
        if (bytes.length < 5)
            // need at least 5 bytes to establish the encoding
            throw new IllegalArgumentException("Malformatted JSON");

        int offset = 0;
        if ((bytes[0] == -1 && bytes[1] == -2)
            || (bytes[0] == -2 && bytes[1] == -1)) {
            // Skip UTF16/UTF32 Byte Order Mark (BOM)
            offset = 2;
        }

        /* Infer the encoding as described in section 3 of http://www.ietf.org/rfc/rfc4627.txt
         * which reads:
         *   Encoding
         *
         *   JSON text SHALL be encoded in Unicode.  The default encoding is
         *   UTF-8.
         *
         *   Since the first two characters of a JSON text will always be ASCII
         *   characters [RFC0020], it is possible to determine whether an octet
         *   stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
         *   at the pattern of nulls in the first four octets.
         *
         *         00 00 00 xx  UTF-32BE
         *         00 xx 00 xx  UTF-16BE
         *         xx 00 00 00  UTF-32LE
         *         xx 00 xx 00  UTF-16LE
         *         xx xx xx xx  UTF-8
         */
        String encoding;
        if (bytes[offset + 2] == 0) {
            if (bytes[offset + 1] != 0) {
                encoding = "UTF-16";
            } else {
                encoding = "UTF-32";
            }
        } else if (bytes[offset + 1] == 0) {
            encoding = "UTF-16";
        } else {
            encoding = "UTF-8";
        }
        return new String(bytes, encoding);
    }
    
    public static byte [] readStream(InputStream is) throws IOException {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] bytes = new byte[8192];

            int length = 0;
            int offset = 0;

            while ((length = is.read(bytes, offset, bytes.length - offset)) != -1) {
                offset += length;

                if (offset == bytes.length) {
                    baos.write(bytes, 0, bytes.length);
                    offset = 0;
                }
            }
            if (offset != 0) {
                baos.write(bytes, 0, offset);
            }
            return baos.toByteArray();
        } finally {
            is.close();
        }
    }
}