/*
 * 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 thrift

import (
	"bufio"
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"math"
	"strconv"
)

type _ParseContext int

const (
	_CONTEXT_INVALID              _ParseContext = iota
	_CONTEXT_IN_TOPLEVEL                        // 1
	_CONTEXT_IN_LIST_FIRST                      // 2
	_CONTEXT_IN_LIST                            // 3
	_CONTEXT_IN_OBJECT_FIRST                    // 4
	_CONTEXT_IN_OBJECT_NEXT_KEY                 // 5
	_CONTEXT_IN_OBJECT_NEXT_VALUE               // 6
)

func (p _ParseContext) String() string {
	switch p {
	case _CONTEXT_IN_TOPLEVEL:
		return "TOPLEVEL"
	case _CONTEXT_IN_LIST_FIRST:
		return "LIST-FIRST"
	case _CONTEXT_IN_LIST:
		return "LIST"
	case _CONTEXT_IN_OBJECT_FIRST:
		return "OBJECT-FIRST"
	case _CONTEXT_IN_OBJECT_NEXT_KEY:
		return "OBJECT-NEXT-KEY"
	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
		return "OBJECT-NEXT-VALUE"
	}
	return "UNKNOWN-PARSE-CONTEXT"
}

type jsonContextStack []_ParseContext

func (s *jsonContextStack) push(v _ParseContext) {
	*s = append(*s, v)
}

func (s jsonContextStack) peek() (v _ParseContext, ok bool) {
	l := len(s)
	if l <= 0 {
		return
	}
	return s[l-1], true
}

func (s *jsonContextStack) pop() (v _ParseContext, ok bool) {
	l := len(*s)
	if l <= 0 {
		return
	}
	v = (*s)[l-1]
	*s = (*s)[0 : l-1]
	return v, true
}

var errEmptyJSONContextStack = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Unexpected empty json protocol context stack"))

// Simple JSON protocol implementation for thrift.
//
// This protocol produces/consumes a simple output format
// suitable for parsing by scripting languages.  It should not be
// confused with the full-featured TJSONProtocol.
//
type TSimpleJSONProtocol struct {
	trans TTransport

	parseContextStack jsonContextStack
	dumpContext       jsonContextStack

	writer *bufio.Writer
	reader *bufio.Reader
}

// Constructor
func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
	v := &TSimpleJSONProtocol{trans: t,
		writer: bufio.NewWriter(t),
		reader: bufio.NewReader(t),
	}
	v.parseContextStack.push(_CONTEXT_IN_TOPLEVEL)
	v.dumpContext.push(_CONTEXT_IN_TOPLEVEL)
	return v
}

// Factory
type TSimpleJSONProtocolFactory struct{}

func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
	return NewTSimpleJSONProtocol(trans)
}

func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
	return &TSimpleJSONProtocolFactory{}
}

var (
	JSON_COMMA                   []byte
	JSON_COLON                   []byte
	JSON_LBRACE                  []byte
	JSON_RBRACE                  []byte
	JSON_LBRACKET                []byte
	JSON_RBRACKET                []byte
	JSON_QUOTE                   byte
	JSON_QUOTE_BYTES             []byte
	JSON_NULL                    []byte
	JSON_TRUE                    []byte
	JSON_FALSE                   []byte
	JSON_INFINITY                string
	JSON_NEGATIVE_INFINITY       string
	JSON_NAN                     string
	JSON_INFINITY_BYTES          []byte
	JSON_NEGATIVE_INFINITY_BYTES []byte
	JSON_NAN_BYTES               []byte
	json_nonbase_map_elem_bytes  []byte
)

func init() {
	JSON_COMMA = []byte{','}
	JSON_COLON = []byte{':'}
	JSON_LBRACE = []byte{'{'}
	JSON_RBRACE = []byte{'}'}
	JSON_LBRACKET = []byte{'['}
	JSON_RBRACKET = []byte{']'}
	JSON_QUOTE = '"'
	JSON_QUOTE_BYTES = []byte{'"'}
	JSON_NULL = []byte{'n', 'u', 'l', 'l'}
	JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
	JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
	JSON_INFINITY = "Infinity"
	JSON_NEGATIVE_INFINITY = "-Infinity"
	JSON_NAN = "NaN"
	JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
	JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
	JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
	json_nonbase_map_elem_bytes = []byte{']', ',', '['}
}

func jsonQuote(s string) string {
	b, _ := json.Marshal(s)
	s1 := string(b)
	return s1
}

func jsonUnquote(s string) (string, bool) {
	s1 := new(string)
	err := json.Unmarshal([]byte(s), s1)
	return *s1, err == nil
}

func mismatch(expected, actual string) error {
	return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual)
}

func (p *TSimpleJSONProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error {
	p.resetContextStack() // THRIFT-3735
	if e := p.OutputListBegin(); e != nil {
		return e
	}
	if e := p.WriteString(ctx, name); e != nil {
		return e
	}
	if e := p.WriteByte(ctx, int8(typeId)); e != nil {
		return e
	}
	if e := p.WriteI32(ctx, seqId); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) WriteMessageEnd(ctx context.Context) error {
	return p.OutputListEnd()
}

func (p *TSimpleJSONProtocol) WriteStructBegin(ctx context.Context, name string) error {
	if e := p.OutputObjectBegin(); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) WriteStructEnd(ctx context.Context) error {
	return p.OutputObjectEnd()
}

func (p *TSimpleJSONProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error {
	if e := p.WriteString(ctx, name); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) WriteFieldEnd(ctx context.Context) error {
	return nil
}

func (p *TSimpleJSONProtocol) WriteFieldStop(ctx context.Context) error { return nil }

func (p *TSimpleJSONProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error {
	if e := p.OutputListBegin(); e != nil {
		return e
	}
	if e := p.WriteByte(ctx, int8(keyType)); e != nil {
		return e
	}
	if e := p.WriteByte(ctx, int8(valueType)); e != nil {
		return e
	}
	return p.WriteI32(ctx, int32(size))
}

func (p *TSimpleJSONProtocol) WriteMapEnd(ctx context.Context) error {
	return p.OutputListEnd()
}

func (p *TSimpleJSONProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error {
	return p.OutputElemListBegin(elemType, size)
}

func (p *TSimpleJSONProtocol) WriteListEnd(ctx context.Context) error {
	return p.OutputListEnd()
}

func (p *TSimpleJSONProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error {
	return p.OutputElemListBegin(elemType, size)
}

func (p *TSimpleJSONProtocol) WriteSetEnd(ctx context.Context) error {
	return p.OutputListEnd()
}

func (p *TSimpleJSONProtocol) WriteBool(ctx context.Context, b bool) error {
	return p.OutputBool(b)
}

func (p *TSimpleJSONProtocol) WriteByte(ctx context.Context, b int8) error {
	return p.WriteI32(ctx, int32(b))
}

func (p *TSimpleJSONProtocol) WriteI16(ctx context.Context, v int16) error {
	return p.WriteI32(ctx, int32(v))
}

func (p *TSimpleJSONProtocol) WriteI32(ctx context.Context, v int32) error {
	return p.OutputI64(int64(v))
}

func (p *TSimpleJSONProtocol) WriteI64(ctx context.Context, v int64) error {
	return p.OutputI64(int64(v))
}

func (p *TSimpleJSONProtocol) WriteDouble(ctx context.Context, v float64) error {
	return p.OutputF64(v)
}

func (p *TSimpleJSONProtocol) WriteString(ctx context.Context, v string) error {
	return p.OutputString(v)
}

func (p *TSimpleJSONProtocol) WriteBinary(ctx context.Context, v []byte) error {
	// JSON library only takes in a string,
	// not an arbitrary byte array, to ensure bytes are transmitted
	// efficiently we must convert this into a valid JSON string
	// therefore we use base64 encoding to avoid excessive escaping/quoting
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
		return NewTProtocolException(e)
	}
	writer := base64.NewEncoder(base64.StdEncoding, p.writer)
	if _, e := writer.Write(v); e != nil {
		p.writer.Reset(p.trans) // THRIFT-3735
		return NewTProtocolException(e)
	}
	if e := writer.Close(); e != nil {
		return NewTProtocolException(e)
	}
	if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
		return NewTProtocolException(e)
	}
	return p.OutputPostValue()
}

// Reading methods.
func (p *TSimpleJSONProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) {
	p.resetContextStack() // THRIFT-3735
	if isNull, err := p.ParseListBegin(); isNull || err != nil {
		return name, typeId, seqId, err
	}
	if name, err = p.ReadString(ctx); err != nil {
		return name, typeId, seqId, err
	}
	bTypeId, err := p.ReadByte(ctx)
	typeId = TMessageType(bTypeId)
	if err != nil {
		return name, typeId, seqId, err
	}
	if seqId, err = p.ReadI32(ctx); err != nil {
		return name, typeId, seqId, err
	}
	return name, typeId, seqId, nil
}

func (p *TSimpleJSONProtocol) ReadMessageEnd(ctx context.Context) error {
	return p.ParseListEnd()
}

func (p *TSimpleJSONProtocol) ReadStructBegin(ctx context.Context) (name string, err error) {
	_, err = p.ParseObjectStart()
	return "", err
}

func (p *TSimpleJSONProtocol) ReadStructEnd(ctx context.Context) error {
	return p.ParseObjectEnd()
}

func (p *TSimpleJSONProtocol) ReadFieldBegin(ctx context.Context) (string, TType, int16, error) {
	if err := p.ParsePreValue(); err != nil {
		return "", STOP, 0, err
	}
	b, _ := p.reader.Peek(1)
	if len(b) > 0 {
		switch b[0] {
		case JSON_RBRACE[0]:
			return "", STOP, 0, nil
		case JSON_QUOTE:
			p.reader.ReadByte()
			name, err := p.ParseStringBody()
			// simplejson is not meant to be read back into thrift
			// - see http://wiki.apache.org/thrift/ThriftUsageJava
			// - use JSON instead
			if err != nil {
				return name, STOP, 0, err
			}
			return name, STOP, -1, p.ParsePostValue()
		}
		e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b))
		return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	return "", STOP, 0, NewTProtocolException(io.EOF)
}

func (p *TSimpleJSONProtocol) ReadFieldEnd(ctx context.Context) error {
	return nil
}

func (p *TSimpleJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, e error) {
	if isNull, e := p.ParseListBegin(); isNull || e != nil {
		return VOID, VOID, 0, e
	}

	// read keyType
	bKeyType, e := p.ReadByte(ctx)
	keyType = TType(bKeyType)
	if e != nil {
		return keyType, valueType, size, e
	}

	// read valueType
	bValueType, e := p.ReadByte(ctx)
	valueType = TType(bValueType)
	if e != nil {
		return keyType, valueType, size, e
	}

	// read size
	iSize, err := p.ReadI64(ctx)
	size = int(iSize)
	return keyType, valueType, size, err
}

func (p *TSimpleJSONProtocol) ReadMapEnd(ctx context.Context) error {
	return p.ParseListEnd()
}

func (p *TSimpleJSONProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, e error) {
	return p.ParseElemListBegin()
}

func (p *TSimpleJSONProtocol) ReadListEnd(ctx context.Context) error {
	return p.ParseListEnd()
}

func (p *TSimpleJSONProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, e error) {
	return p.ParseElemListBegin()
}

func (p *TSimpleJSONProtocol) ReadSetEnd(ctx context.Context) error {
	return p.ParseListEnd()
}

func (p *TSimpleJSONProtocol) ReadBool(ctx context.Context) (bool, error) {
	var value bool

	if err := p.ParsePreValue(); err != nil {
		return value, err
	}
	f, _ := p.reader.Peek(1)
	if len(f) > 0 {
		switch f[0] {
		case JSON_TRUE[0]:
			b := make([]byte, len(JSON_TRUE))
			_, err := p.reader.Read(b)
			if err != nil {
				return false, NewTProtocolException(err)
			}
			if string(b) == string(JSON_TRUE) {
				value = true
			} else {
				e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			break
		case JSON_FALSE[0]:
			b := make([]byte, len(JSON_FALSE))
			_, err := p.reader.Read(b)
			if err != nil {
				return false, NewTProtocolException(err)
			}
			if string(b) == string(JSON_FALSE) {
				value = false
			} else {
				e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			break
		case JSON_NULL[0]:
			b := make([]byte, len(JSON_NULL))
			_, err := p.reader.Read(b)
			if err != nil {
				return false, NewTProtocolException(err)
			}
			if string(b) == string(JSON_NULL) {
				value = false
			} else {
				e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		default:
			e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f))
			return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
		}
	}
	return value, p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) ReadByte(ctx context.Context) (int8, error) {
	v, err := p.ReadI64(ctx)
	return int8(v), err
}

func (p *TSimpleJSONProtocol) ReadI16(ctx context.Context) (int16, error) {
	v, err := p.ReadI64(ctx)
	return int16(v), err
}

func (p *TSimpleJSONProtocol) ReadI32(ctx context.Context) (int32, error) {
	v, err := p.ReadI64(ctx)
	return int32(v), err
}

func (p *TSimpleJSONProtocol) ReadI64(ctx context.Context) (int64, error) {
	v, _, err := p.ParseI64()
	return v, err
}

func (p *TSimpleJSONProtocol) ReadDouble(ctx context.Context) (float64, error) {
	v, _, err := p.ParseF64()
	return v, err
}

func (p *TSimpleJSONProtocol) ReadString(ctx context.Context) (string, error) {
	var v string
	if err := p.ParsePreValue(); err != nil {
		return v, err
	}
	f, _ := p.reader.Peek(1)
	if len(f) > 0 && f[0] == JSON_QUOTE {
		p.reader.ReadByte()
		value, err := p.ParseStringBody()
		v = value
		if err != nil {
			return v, err
		}
	} else if len(f) > 0 && f[0] == JSON_NULL[0] {
		b := make([]byte, len(JSON_NULL))
		_, err := p.reader.Read(b)
		if err != nil {
			return v, NewTProtocolException(err)
		}
		if string(b) != string(JSON_NULL) {
			e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
			return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
		}
	} else {
		e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	return v, p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) ReadBinary(ctx context.Context) ([]byte, error) {
	var v []byte
	if err := p.ParsePreValue(); err != nil {
		return nil, err
	}
	f, _ := p.reader.Peek(1)
	if len(f) > 0 && f[0] == JSON_QUOTE {
		p.reader.ReadByte()
		value, err := p.ParseBase64EncodedBody()
		v = value
		if err != nil {
			return v, err
		}
	} else if len(f) > 0 && f[0] == JSON_NULL[0] {
		b := make([]byte, len(JSON_NULL))
		_, err := p.reader.Read(b)
		if err != nil {
			return v, NewTProtocolException(err)
		}
		if string(b) != string(JSON_NULL) {
			e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
			return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
		}
	} else {
		e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
	}

	return v, p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) {
	return NewTProtocolException(p.writer.Flush())
}

func (p *TSimpleJSONProtocol) Skip(ctx context.Context, fieldType TType) (err error) {
	return SkipDefaultDepth(ctx, p, fieldType)
}

func (p *TSimpleJSONProtocol) Transport() TTransport {
	return p.trans
}

func (p *TSimpleJSONProtocol) OutputPreValue() error {
	cxt, ok := p.dumpContext.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	switch cxt {
	case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
		if _, e := p.write(JSON_COMMA); e != nil {
			return NewTProtocolException(e)
		}
	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
		if _, e := p.write(JSON_COLON); e != nil {
			return NewTProtocolException(e)
		}
	}
	return nil
}

func (p *TSimpleJSONProtocol) OutputPostValue() error {
	cxt, ok := p.dumpContext.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	switch cxt {
	case _CONTEXT_IN_LIST_FIRST:
		p.dumpContext.pop()
		p.dumpContext.push(_CONTEXT_IN_LIST)
	case _CONTEXT_IN_OBJECT_FIRST:
		p.dumpContext.pop()
		p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
	case _CONTEXT_IN_OBJECT_NEXT_KEY:
		p.dumpContext.pop()
		p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
		p.dumpContext.pop()
		p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_KEY)
	}
	return nil
}

func (p *TSimpleJSONProtocol) OutputBool(value bool) error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	var v string
	if value {
		v = string(JSON_TRUE)
	} else {
		v = string(JSON_FALSE)
	}
	cxt, ok := p.dumpContext.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	switch cxt {
	case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
		v = jsonQuote(v)
	}
	if e := p.OutputStringData(v); e != nil {
		return e
	}
	return p.OutputPostValue()
}

func (p *TSimpleJSONProtocol) OutputNull() error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	if _, e := p.write(JSON_NULL); e != nil {
		return NewTProtocolException(e)
	}
	return p.OutputPostValue()
}

func (p *TSimpleJSONProtocol) OutputF64(value float64) error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	var v string
	if math.IsNaN(value) {
		v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
	} else if math.IsInf(value, 1) {
		v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
	} else if math.IsInf(value, -1) {
		v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
	} else {
		cxt, ok := p.dumpContext.peek()
		if !ok {
			return errEmptyJSONContextStack
		}
		v = strconv.FormatFloat(value, 'g', -1, 64)
		switch cxt {
		case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
			v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
		}
	}
	if e := p.OutputStringData(v); e != nil {
		return e
	}
	return p.OutputPostValue()
}

func (p *TSimpleJSONProtocol) OutputI64(value int64) error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	cxt, ok := p.dumpContext.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	v := strconv.FormatInt(value, 10)
	switch cxt {
	case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
		v = jsonQuote(v)
	}
	if e := p.OutputStringData(v); e != nil {
		return e
	}
	return p.OutputPostValue()
}

func (p *TSimpleJSONProtocol) OutputString(s string) error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	if e := p.OutputStringData(jsonQuote(s)); e != nil {
		return e
	}
	return p.OutputPostValue()
}

func (p *TSimpleJSONProtocol) OutputStringData(s string) error {
	_, e := p.write([]byte(s))
	return NewTProtocolException(e)
}

func (p *TSimpleJSONProtocol) OutputObjectBegin() error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	if _, e := p.write(JSON_LBRACE); e != nil {
		return NewTProtocolException(e)
	}
	p.dumpContext.push(_CONTEXT_IN_OBJECT_FIRST)
	return nil
}

func (p *TSimpleJSONProtocol) OutputObjectEnd() error {
	if _, e := p.write(JSON_RBRACE); e != nil {
		return NewTProtocolException(e)
	}
	_, ok := p.dumpContext.pop()
	if !ok {
		return errEmptyJSONContextStack
	}
	if e := p.OutputPostValue(); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) OutputListBegin() error {
	if e := p.OutputPreValue(); e != nil {
		return e
	}
	if _, e := p.write(JSON_LBRACKET); e != nil {
		return NewTProtocolException(e)
	}
	p.dumpContext.push(_CONTEXT_IN_LIST_FIRST)
	return nil
}

func (p *TSimpleJSONProtocol) OutputListEnd() error {
	if _, e := p.write(JSON_RBRACKET); e != nil {
		return NewTProtocolException(e)
	}
	_, ok := p.dumpContext.pop()
	if !ok {
		return errEmptyJSONContextStack
	}
	if e := p.OutputPostValue(); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
	if e := p.OutputListBegin(); e != nil {
		return e
	}
	if e := p.OutputI64(int64(elemType)); e != nil {
		return e
	}
	if e := p.OutputI64(int64(size)); e != nil {
		return e
	}
	return nil
}

func (p *TSimpleJSONProtocol) ParsePreValue() error {
	if e := p.readNonSignificantWhitespace(); e != nil {
		return NewTProtocolException(e)
	}
	cxt, ok := p.parseContextStack.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	b, _ := p.reader.Peek(1)
	switch cxt {
	case _CONTEXT_IN_LIST:
		if len(b) > 0 {
			switch b[0] {
			case JSON_RBRACKET[0]:
				return nil
			case JSON_COMMA[0]:
				p.reader.ReadByte()
				if e := p.readNonSignificantWhitespace(); e != nil {
					return NewTProtocolException(e)
				}
				return nil
			default:
				e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b))
				return NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		}
	case _CONTEXT_IN_OBJECT_NEXT_KEY:
		if len(b) > 0 {
			switch b[0] {
			case JSON_RBRACE[0]:
				return nil
			case JSON_COMMA[0]:
				p.reader.ReadByte()
				if e := p.readNonSignificantWhitespace(); e != nil {
					return NewTProtocolException(e)
				}
				return nil
			default:
				e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b))
				return NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		}
	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
		if len(b) > 0 {
			switch b[0] {
			case JSON_COLON[0]:
				p.reader.ReadByte()
				if e := p.readNonSignificantWhitespace(); e != nil {
					return NewTProtocolException(e)
				}
				return nil
			default:
				e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b))
				return NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		}
	}
	return nil
}

func (p *TSimpleJSONProtocol) ParsePostValue() error {
	if e := p.readNonSignificantWhitespace(); e != nil {
		return NewTProtocolException(e)
	}
	cxt, ok := p.parseContextStack.peek()
	if !ok {
		return errEmptyJSONContextStack
	}
	switch cxt {
	case _CONTEXT_IN_LIST_FIRST:
		p.parseContextStack.pop()
		p.parseContextStack.push(_CONTEXT_IN_LIST)
	case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
		p.parseContextStack.pop()
		p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
		p.parseContextStack.pop()
		p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_KEY)
	}
	return nil
}

func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error {
	for {
		b, _ := p.reader.Peek(1)
		if len(b) < 1 {
			return nil
		}
		switch b[0] {
		case ' ', '\r', '\n', '\t':
			p.reader.ReadByte()
			continue
		default:
			break
		}
		break
	}
	return nil
}

func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) {
	line, err := p.reader.ReadString(JSON_QUOTE)
	if err != nil {
		return "", NewTProtocolException(err)
	}
	l := len(line)
	// count number of escapes to see if we need to keep going
	i := 1
	for ; i < l; i++ {
		if line[l-i-1] != '\\' {
			break
		}
	}
	if i&0x01 == 1 {
		v, ok := jsonUnquote(string(JSON_QUOTE) + line)
		if !ok {
			return "", NewTProtocolException(err)
		}
		return v, nil
	}
	s, err := p.ParseQuotedStringBody()
	if err != nil {
		return "", NewTProtocolException(err)
	}
	str := string(JSON_QUOTE) + line + s
	v, ok := jsonUnquote(str)
	if !ok {
		e := fmt.Errorf("Unable to parse as JSON string %s", str)
		return "", NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	return v, nil
}

func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) {
	line, err := p.reader.ReadString(JSON_QUOTE)
	if err != nil {
		return "", NewTProtocolException(err)
	}
	l := len(line)
	// count number of escapes to see if we need to keep going
	i := 1
	for ; i < l; i++ {
		if line[l-i-1] != '\\' {
			break
		}
	}
	if i&0x01 == 1 {
		return line, nil
	}
	s, err := p.ParseQuotedStringBody()
	if err != nil {
		return "", NewTProtocolException(err)
	}
	v := line + s
	return v, nil
}

func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) {
	line, err := p.reader.ReadBytes(JSON_QUOTE)
	if err != nil {
		return line, NewTProtocolException(err)
	}
	line2 := line[0 : len(line)-1]
	l := len(line2)
	if (l % 4) != 0 {
		pad := 4 - (l % 4)
		fill := [...]byte{'=', '=', '='}
		line2 = append(line2, fill[:pad]...)
		l = len(line2)
	}
	output := make([]byte, base64.StdEncoding.DecodedLen(l))
	n, err := base64.StdEncoding.Decode(output, line2)
	return output[0:n], NewTProtocolException(err)
}

func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) {
	if err := p.ParsePreValue(); err != nil {
		return 0, false, err
	}
	var value int64
	var isnull bool
	if p.safePeekContains(JSON_NULL) {
		p.reader.Read(make([]byte, len(JSON_NULL)))
		isnull = true
	} else {
		num, err := p.readNumeric()
		isnull = (num == nil)
		if !isnull {
			value = num.Int64()
		}
		if err != nil {
			return value, isnull, err
		}
	}
	return value, isnull, p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) {
	if err := p.ParsePreValue(); err != nil {
		return 0, false, err
	}
	var value float64
	var isnull bool
	if p.safePeekContains(JSON_NULL) {
		p.reader.Read(make([]byte, len(JSON_NULL)))
		isnull = true
	} else {
		num, err := p.readNumeric()
		isnull = (num == nil)
		if !isnull {
			value = num.Float64()
		}
		if err != nil {
			return value, isnull, err
		}
	}
	return value, isnull, p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) {
	if err := p.ParsePreValue(); err != nil {
		return false, err
	}
	var b []byte
	b, err := p.reader.Peek(1)
	if err != nil {
		return false, err
	}
	if len(b) > 0 && b[0] == JSON_LBRACE[0] {
		p.reader.ReadByte()
		p.parseContextStack.push(_CONTEXT_IN_OBJECT_FIRST)
		return false, nil
	} else if p.safePeekContains(JSON_NULL) {
		return true, nil
	}
	e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b))
	return false, NewTProtocolExceptionWithType(INVALID_DATA, e)
}

func (p *TSimpleJSONProtocol) ParseObjectEnd() error {
	if isNull, err := p.readIfNull(); isNull || err != nil {
		return err
	}
	cxt, _ := p.parseContextStack.peek()
	if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) {
		e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt)
		return NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	line, err := p.reader.ReadString(JSON_RBRACE[0])
	if err != nil {
		return NewTProtocolException(err)
	}
	for _, char := range line {
		switch char {
		default:
			e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line)
			return NewTProtocolExceptionWithType(INVALID_DATA, e)
		case ' ', '\n', '\r', '\t', '}':
			break
		}
	}
	p.parseContextStack.pop()
	return p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) {
	if e := p.ParsePreValue(); e != nil {
		return false, e
	}
	var b []byte
	b, err = p.reader.Peek(1)
	if err != nil {
		return false, err
	}
	if len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
		p.parseContextStack.push(_CONTEXT_IN_LIST_FIRST)
		p.reader.ReadByte()
		isNull = false
	} else if p.safePeekContains(JSON_NULL) {
		isNull = true
	} else {
		err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b)
	}
	return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err)
}

func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
	if isNull, e := p.ParseListBegin(); isNull || e != nil {
		return VOID, 0, e
	}
	bElemType, _, err := p.ParseI64()
	elemType = TType(bElemType)
	if err != nil {
		return elemType, size, err
	}
	nSize, _, err2 := p.ParseI64()
	size = int(nSize)
	return elemType, size, err2
}

func (p *TSimpleJSONProtocol) ParseListEnd() error {
	if isNull, err := p.readIfNull(); isNull || err != nil {
		return err
	}
	cxt, _ := p.parseContextStack.peek()
	if cxt != _CONTEXT_IN_LIST {
		e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt)
		return NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	line, err := p.reader.ReadString(JSON_RBRACKET[0])
	if err != nil {
		return NewTProtocolException(err)
	}
	for _, char := range line {
		switch char {
		default:
			e := fmt.Errorf("Expecting end of list \"]\", but found: \"%v\"", line)
			return NewTProtocolExceptionWithType(INVALID_DATA, e)
		case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]):
			break
		}
	}
	p.parseContextStack.pop()
	if cxt, ok := p.parseContextStack.peek(); !ok {
		return errEmptyJSONContextStack
	} else if cxt == _CONTEXT_IN_TOPLEVEL {
		return nil
	}
	return p.ParsePostValue()
}

func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) {
	e := p.readNonSignificantWhitespace()
	if e != nil {
		return nil, VOID, NewTProtocolException(e)
	}
	b, e := p.reader.Peek(1)
	if len(b) > 0 {
		c := b[0]
		switch c {
		case JSON_NULL[0]:
			buf := make([]byte, len(JSON_NULL))
			_, e := p.reader.Read(buf)
			if e != nil {
				return nil, VOID, NewTProtocolException(e)
			}
			if string(JSON_NULL) != string(buf) {
				e = mismatch(string(JSON_NULL), string(buf))
				return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			return nil, VOID, nil
		case JSON_QUOTE:
			p.reader.ReadByte()
			v, e := p.ParseStringBody()
			if e != nil {
				return v, UTF8, NewTProtocolException(e)
			}
			if v == JSON_INFINITY {
				return INFINITY, DOUBLE, nil
			} else if v == JSON_NEGATIVE_INFINITY {
				return NEGATIVE_INFINITY, DOUBLE, nil
			} else if v == JSON_NAN {
				return NAN, DOUBLE, nil
			}
			return v, UTF8, nil
		case JSON_TRUE[0]:
			buf := make([]byte, len(JSON_TRUE))
			_, e := p.reader.Read(buf)
			if e != nil {
				return true, BOOL, NewTProtocolException(e)
			}
			if string(JSON_TRUE) != string(buf) {
				e := mismatch(string(JSON_TRUE), string(buf))
				return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			return true, BOOL, nil
		case JSON_FALSE[0]:
			buf := make([]byte, len(JSON_FALSE))
			_, e := p.reader.Read(buf)
			if e != nil {
				return false, BOOL, NewTProtocolException(e)
			}
			if string(JSON_FALSE) != string(buf) {
				e := mismatch(string(JSON_FALSE), string(buf))
				return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			return false, BOOL, nil
		case JSON_LBRACKET[0]:
			_, e := p.reader.ReadByte()
			return make([]interface{}, 0), LIST, NewTProtocolException(e)
		case JSON_LBRACE[0]:
			_, e := p.reader.ReadByte()
			return make(map[string]interface{}), STRUCT, NewTProtocolException(e)
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
			// assume numeric
			v, e := p.readNumeric()
			return v, DOUBLE, e
		default:
			e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c))
			return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
		}
	}
	e = fmt.Errorf("Cannot read a single element while parsing JSON.")
	return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)

}

func (p *TSimpleJSONProtocol) readIfNull() (bool, error) {
	cont := true
	for cont {
		b, _ := p.reader.Peek(1)
		if len(b) < 1 {
			return false, nil
		}
		switch b[0] {
		default:
			return false, nil
		case JSON_NULL[0]:
			cont = false
			break
		case ' ', '\n', '\r', '\t':
			p.reader.ReadByte()
			break
		}
	}
	if p.safePeekContains(JSON_NULL) {
		p.reader.Read(make([]byte, len(JSON_NULL)))
		return true, nil
	}
	return false, nil
}

func (p *TSimpleJSONProtocol) readQuoteIfNext() {
	b, _ := p.reader.Peek(1)
	if len(b) > 0 && b[0] == JSON_QUOTE {
		p.reader.ReadByte()
	}
}

func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) {
	isNull, err := p.readIfNull()
	if isNull || err != nil {
		return NUMERIC_NULL, err
	}
	hasDecimalPoint := false
	nextCanBeSign := true
	hasE := false
	MAX_LEN := 40
	buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
	continueFor := true
	inQuotes := false
	for continueFor {
		c, err := p.reader.ReadByte()
		if err != nil {
			if err == io.EOF {
				break
			}
			return NUMERIC_NULL, NewTProtocolException(err)
		}
		switch c {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			buf.WriteByte(c)
			nextCanBeSign = false
		case '.':
			if hasDecimalPoint {
				e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			if hasE {
				e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			buf.WriteByte(c)
			hasDecimalPoint, nextCanBeSign = true, false
		case 'e', 'E':
			if hasE {
				e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			buf.WriteByte(c)
			hasE, nextCanBeSign = true, true
		case '-', '+':
			if !nextCanBeSign {
				e := fmt.Errorf("Negative sign within number")
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
			buf.WriteByte(c)
			nextCanBeSign = false
		case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
			p.reader.UnreadByte()
			continueFor = false
		case JSON_NAN[0]:
			if buf.Len() == 0 {
				buffer := make([]byte, len(JSON_NAN))
				buffer[0] = c
				_, e := p.reader.Read(buffer[1:])
				if e != nil {
					return NUMERIC_NULL, NewTProtocolException(e)
				}
				if JSON_NAN != string(buffer) {
					e := mismatch(JSON_NAN, string(buffer))
					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
				}
				if inQuotes {
					p.readQuoteIfNext()
				}
				return NAN, nil
			} else {
				e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		case JSON_INFINITY[0]:
			if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
				buffer := make([]byte, len(JSON_INFINITY))
				buffer[0] = c
				_, e := p.reader.Read(buffer[1:])
				if e != nil {
					return NUMERIC_NULL, NewTProtocolException(e)
				}
				if JSON_INFINITY != string(buffer) {
					e := mismatch(JSON_INFINITY, string(buffer))
					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
				}
				if inQuotes {
					p.readQuoteIfNext()
				}
				return INFINITY, nil
			} else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
				buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
				buffer[0] = JSON_NEGATIVE_INFINITY[0]
				buffer[1] = c
				_, e := p.reader.Read(buffer[2:])
				if e != nil {
					return NUMERIC_NULL, NewTProtocolException(e)
				}
				if JSON_NEGATIVE_INFINITY != string(buffer) {
					e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
				}
				if inQuotes {
					p.readQuoteIfNext()
				}
				return NEGATIVE_INFINITY, nil
			} else {
				e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
			}
		case JSON_QUOTE:
			if !inQuotes {
				inQuotes = true
			} else {
				break
			}
		default:
			e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
			return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
		}
	}
	if buf.Len() == 0 {
		e := fmt.Errorf("Unable to parse number from empty string ''")
		return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
	}
	return NewNumericFromJSONString(buf.String(), false), nil
}

// Safely peeks into the buffer, reading only what is necessary
func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool {
	for i := 0; i < len(b); i++ {
		a, _ := p.reader.Peek(i + 1)
		if len(a) < (i+1) || a[i] != b[i] {
			return false
		}
	}
	return true
}

// Reset the context stack to its initial state.
func (p *TSimpleJSONProtocol) resetContextStack() {
	p.parseContextStack = jsonContextStack{_CONTEXT_IN_TOPLEVEL}
	p.dumpContext = jsonContextStack{_CONTEXT_IN_TOPLEVEL}
}

func (p *TSimpleJSONProtocol) write(b []byte) (int, error) {
	n, err := p.writer.Write(b)
	if err != nil {
		p.writer.Reset(p.trans) // THRIFT-3735
	}
	return n, err
}

// SetTConfiguration implements TConfigurationSetter for propagation.
func (p *TSimpleJSONProtocol) SetTConfiguration(conf *TConfiguration) {
	PropagateTConfiguration(p.trans, conf)
}

var _ TConfigurationSetter = (*TSimpleJSONProtocol)(nil)
