/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.onosproject.ovsdb.rfc.utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;

import java.io.IOException;
import java.util.List;
import java.util.Stack;

import org.onosproject.ovsdb.rfc.error.UnsupportedException;
import org.onosproject.ovsdb.rfc.jsonrpc.JsonReadContext;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
import com.fasterxml.jackson.core.util.BufferRecycler;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingJsonFactory;

/**
 * Decoder utility class.
 */
public final class JsonRpcReaderUtil {

    /**
     * Constructs a JsonRpcReaderUtil object. Utility classes should not have a
     * public or default constructor, otherwise IDE will compile unsuccessfully.
     * This class should not be instantiated.
     */
    private JsonRpcReaderUtil() {
    }

    /**
     * Decode the bytes to Json object.
     * @param in input of bytes
     * @param out ouput of Json object list
     * @param jrContext context for the last decoding process
     * @throws IOException IOException
     * @throws JsonParseException JsonParseException
     */
    public static void readToJsonNode(ByteBuf in, List<Object> out, JsonReadContext jrContext)
            throws JsonParseException, IOException {
        int lastReadBytes = jrContext.getLastReadBytes();
        if (lastReadBytes == 0) {
            if (in.readableBytes() < 4) {
                return;
            }
            checkEncoding(in);
        }

        int i = lastReadBytes + in.readerIndex();
        Stack<Byte> bufStack = jrContext.getBufStack();
        for (; i < in.writerIndex(); i++) {
            byte b = in.getByte(i);
            switch (b) {
            case '{':
                if (!isDoubleQuote(bufStack)) {
                    bufStack.push(b);
                    jrContext.setStartMatch(true);
                }
                break;
            case '}':
                if (!isDoubleQuote(bufStack)) {
                    bufStack.pop();
                }
                break;
            case '"':
                if (in.getByte(i - 1) != '\\') {
                    if (!bufStack.isEmpty() && bufStack.peek() != '"') {
                        bufStack.push(b);
                    } else {
                        bufStack.pop();
                    }
                }
                break;
            default:
                break;
            }

            if (jrContext.isStartMatch() && bufStack.isEmpty()) {
                ByteBuf buf = in.readSlice(i - in.readerIndex() + 1);
                JsonParser jf = new MappingJsonFactory().createParser(new ByteBufInputStream(buf));
                JsonNode jsonNode = jf.readValueAsTree();
                out.add(jsonNode);
                lastReadBytes = 0;
                jrContext.setLastReadBytes(lastReadBytes);
                break;
            }
        }

        if (i >= in.writerIndex()) {
            lastReadBytes = in.readableBytes();
            jrContext.setLastReadBytes(lastReadBytes);
        }
    }

    /**
     * Filter the invalid characters before decoding.
     * @param in input of bytes
     * @param lastReadBytes the bytes for last decoding incomplete record
     */
    private static void fliterCharaters(ByteBuf in) {
        while (in.isReadable()) {
            int ch = in.getByte(in.readerIndex());
            if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
                break;
            } else {
                in.readByte();
            }
        }
    }

    /**
     * Check whether the peek of the stack element is double quote.
     * @param jrContext context for the last decoding process
     * @return boolean
     */
    private static boolean isDoubleQuote(Stack<Byte> bufStack) {
        if (!bufStack.isEmpty() && bufStack.peek() == '"') {
            return true;
        }
        return false;
    }

    /**
     * Check whether the encoding is valid.
     * @param in input of bytes
     * @throws IOException this is an IO exception
     * @throws UnsupportedException this is an unsupported exception
     */
    private static void checkEncoding(ByteBuf in) throws IOException {
        int inputStart = 0;
        int inputLength = 4;
        fliterCharaters(in);
        byte[] buff = new byte[4];
        in.getBytes(in.readerIndex(), buff);
        ByteSourceJsonBootstrapper strapper = new ByteSourceJsonBootstrapper(new IOContext(new BufferRecycler(),
                                                                                           null,
                                                                                           false),
                                                                             buff, inputStart,
                                                                             inputLength);
        JsonEncoding jsonEncoding = strapper.detectEncoding();
        if (!JsonEncoding.UTF8.equals(jsonEncoding)) {
            throw new UnsupportedException("Only UTF-8 encoding is supported.");
        }
    }

}
