/*
 * 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.exception.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.");
        }
    }

}
