// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build goexperiment.jsonv2

package json

import (
	"bytes"
	"errors"
	"io"

	"encoding/json/jsontext"
	jsonv2 "encoding/json/v2"
)

// A Decoder reads and decodes JSON values from an input stream.
type Decoder struct {
	dec  *jsontext.Decoder
	opts jsonv2.Options
	err  error
}

// NewDecoder returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may
// read data from r beyond the JSON values requested.
func NewDecoder(r io.Reader) *Decoder {
	// Hide bytes.Buffer from jsontext since it implements optimizations that
	// also limits certain ways it could be used. For example, one cannot write
	// to the bytes.Buffer while it is in use by jsontext.Decoder.
	if _, ok := r.(*bytes.Buffer); ok {
		r = struct{ io.Reader }{r}
	}

	dec := new(Decoder)
	dec.opts = DefaultOptionsV1()
	dec.dec = jsontext.NewDecoder(r, dec.opts)
	return dec
}

// UseNumber causes the Decoder to unmarshal a number into an
// interface value as a [Number] instead of as a float64.
func (dec *Decoder) UseNumber() {
	if useNumber, _ := jsonv2.GetOption(dec.opts, unmarshalAnyWithRawNumber); !useNumber {
		dec.opts = jsonv2.JoinOptions(dec.opts, unmarshalAnyWithRawNumber(true))
	}
}

// DisallowUnknownFields causes the Decoder to return an error when the destination
// is a struct and the input contains object keys which do not match any
// non-ignored, exported fields in the destination.
func (dec *Decoder) DisallowUnknownFields() {
	if reject, _ := jsonv2.GetOption(dec.opts, jsonv2.RejectUnknownMembers); !reject {
		dec.opts = jsonv2.JoinOptions(dec.opts, jsonv2.RejectUnknownMembers(true))
	}
}

// Decode reads the next JSON-encoded value from its
// input and stores it in the value pointed to by v.
//
// See the documentation for [Unmarshal] for details about
// the conversion of JSON into a Go value.
func (dec *Decoder) Decode(v any) error {
	if dec.err != nil {
		return dec.err
	}
	b, err := dec.dec.ReadValue()
	if err != nil {
		dec.err = transformSyntacticError(err)
		if dec.err.Error() == errUnexpectedEnd.Error() {
			// NOTE: Decode has always been inconsistent with Unmarshal
			// with regard to the exact error value for truncated input.
			dec.err = io.ErrUnexpectedEOF
		}
		return dec.err
	}
	return jsonv2.Unmarshal(b, v, dec.opts)
}

// Buffered returns a reader of the data remaining in the Decoder's
// buffer. The reader is valid until the next call to [Decoder.Decode].
func (dec *Decoder) Buffered() io.Reader {
	return bytes.NewReader(dec.dec.UnreadBuffer())
}

// An Encoder writes JSON values to an output stream.
type Encoder struct {
	w    io.Writer
	opts jsonv2.Options
	err  error

	buf       bytes.Buffer
	indentBuf bytes.Buffer

	indentPrefix string
	indentValue  string
}

// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
	enc := new(Encoder)
	enc.w = w
	enc.opts = DefaultOptionsV1()
	return enc
}

// Encode writes the JSON encoding of v to the stream,
// followed by a newline character.
//
// See the documentation for [Marshal] for details about the
// conversion of Go values to JSON.
func (enc *Encoder) Encode(v any) error {
	if enc.err != nil {
		return enc.err
	}

	buf := &enc.buf
	buf.Reset()
	if err := jsonv2.MarshalWrite(buf, v, enc.opts); err != nil {
		return err
	}
	if len(enc.indentPrefix)+len(enc.indentValue) > 0 {
		enc.indentBuf.Reset()
		if err := Indent(&enc.indentBuf, buf.Bytes(), enc.indentPrefix, enc.indentValue); err != nil {
			return err
		}
		buf = &enc.indentBuf
	}
	buf.WriteByte('\n')

	if _, err := enc.w.Write(buf.Bytes()); err != nil {
		enc.err = err
		return err
	}
	return nil
}

// SetIndent instructs the encoder to format each subsequent encoded
// value as if indented by the package-level function Indent(dst, src, prefix, indent).
// Calling SetIndent("", "") disables indentation.
func (enc *Encoder) SetIndent(prefix, indent string) {
	enc.indentPrefix = prefix
	enc.indentValue = indent
}

// SetEscapeHTML specifies whether problematic HTML characters
// should be escaped inside JSON quoted strings.
// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
// to avoid certain safety problems that can arise when embedding JSON in HTML.
//
// In non-HTML settings where the escaping interferes with the readability
// of the output, SetEscapeHTML(false) disables this behavior.
func (enc *Encoder) SetEscapeHTML(on bool) {
	if escape, _ := jsonv2.GetOption(enc.opts, jsontext.EscapeForHTML); escape != on {
		enc.opts = jsonv2.JoinOptions(enc.opts, jsontext.EscapeForHTML(on))
	}
}

// RawMessage is a raw encoded JSON value.
// It implements [Marshaler] and [Unmarshaler] and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawMessage = jsontext.Value

// A Token holds a value of one of these types:
//
//   - [Delim], for the four JSON delimiters [ ] { }
//   - bool, for JSON booleans
//   - float64, for JSON numbers
//   - [Number], for JSON numbers
//   - string, for JSON string literals
//   - nil, for JSON null
type Token any

// A Delim is a JSON array or object delimiter, one of [ ] { or }.
type Delim rune

func (d Delim) String() string {
	return string(d)
}

// Token returns the next JSON token in the input stream.
// At the end of the input stream, Token returns nil, [io.EOF].
//
// Token guarantees that the delimiters [ ] { } it returns are
// properly nested and matched: if Token encounters an unexpected
// delimiter in the input, it will return an error.
//
// The input stream consists of basic JSON values—bool, string,
// number, and null—along with delimiters [ ] { } of type [Delim]
// to mark the start and end of arrays and objects.
// Commas and colons are elided.
func (dec *Decoder) Token() (Token, error) {
	tok, err := dec.dec.ReadToken()
	if err != nil {
		// Historically, v1 would report just [io.EOF] if
		// the stream is a prefix of a valid JSON value.
		// It reports an unwrapped [io.ErrUnexpectedEOF] if
		// truncated within a JSON token such as a literal, number, or string.
		if errors.Is(err, io.ErrUnexpectedEOF) {
			if len(bytes.Trim(dec.dec.UnreadBuffer(), " \r\n\t,:")) == 0 {
				return nil, io.EOF
			}
			return nil, io.ErrUnexpectedEOF
		}
		return nil, transformSyntacticError(err)
	}
	switch k := tok.Kind(); k {
	case 'n':
		return nil, nil
	case 'f':
		return false, nil
	case 't':
		return true, nil
	case '"':
		return tok.String(), nil
	case '0':
		if useNumber, _ := jsonv2.GetOption(dec.opts, unmarshalAnyWithRawNumber); useNumber {
			return Number(tok.String()), nil
		}
		return tok.Float(), nil
	case '{', '}', '[', ']':
		return Delim(k), nil
	default:
		panic("unreachable")
	}
}

// More reports whether there is another element in the
// current array or object being parsed.
func (dec *Decoder) More() bool {
	k := dec.dec.PeekKind()
	return k > 0 && k != ']' && k != '}'
}

// InputOffset returns the input stream byte offset of the current decoder position.
// The offset gives the location of the end of the most recently returned token
// and the beginning of the next token.
func (dec *Decoder) InputOffset() int64 {
	return dec.dec.InputOffset()
}
