// Copyright 2020 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 (
	"cmp"
	"errors"
	"fmt"
	"io"
	"reflect"
	"strconv"
	"strings"
	"sync"

	"encoding/json/internal/jsonflags"
	"encoding/json/internal/jsonopts"
	"encoding/json/internal/jsonwire"
	"encoding/json/jsontext"
)

// ErrUnknownName indicates that a JSON object member could not be
// unmarshaled because the name is not known to the target Go struct.
// This error is directly wrapped within a [SemanticError] when produced.
//
// The name of an unknown JSON object member can be extracted as:
//
//	err := ...
//	serr, ok := errors.AsType[*json.SemanticError](err)
//	if ok && serr.Err == json.ErrUnknownName {
//		ptr := serr.JSONPointer // JSON pointer to unknown name
//		name := ptr.LastToken() // unknown name itself
//		...
//	}
//
// This error is only returned if [RejectUnknownMembers] is true.
var ErrUnknownName = errors.New("unknown object member name")

// errAmbiguousName indicates a JSON object member could be unmarshal
// into multiple candidate Go struct fields.
var errAmbiguousName = errors.New("ambiguous object member name")

const errorPrefix = "json: "

func isSemanticError(err error) bool {
	_, ok := err.(*SemanticError)
	return ok
}

func isSyntacticError(err error) bool {
	_, ok := err.(*jsontext.SyntacticError)
	return ok
}

// isFatalError reports whether this error must terminate arshaling.
// All errors are considered fatal unless operating under
// [jsonflags.ReportErrorsWithLegacySemantics] in which case only
// syntactic errors and I/O errors are considered fatal.
func isFatalError(err error, flags jsonflags.Flags) bool {
	return !flags.Get(jsonflags.ReportErrorsWithLegacySemantics) ||
		isSyntacticError(err) || export.IsIOError(err)
}

// SemanticError describes an error determining the meaning
// of JSON data as Go data or vice-versa.
//
// If a [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom] method
// returns a SemanticError when called by the [json] package,
// then the ByteOffset, JSONPointer, and GoType fields are automatically
// populated by the calling context if they are the zero value.
//
// The contents of this error as produced by this package may change over time.
type SemanticError struct {
	requireKeyedLiterals
	nonComparable

	action string // either "marshal" or "unmarshal"

	// ByteOffset indicates that an error occurred at or after this byte offset.
	ByteOffset int64
	// JSONPointer indicates that an error occurred within this JSON value
	// as indicated using the JSON Pointer notation (see RFC 6901).
	JSONPointer jsontext.Pointer

	// JSONKind is the JSON kind that could not be handled.
	JSONKind jsontext.Kind // may be zero if unknown
	// JSONValue is the JSON number or string that could not be unmarshaled.
	// It is not populated during marshaling.
	JSONValue jsontext.Value // may be nil if irrelevant or unknown
	// GoType is the Go type that could not be handled.
	GoType reflect.Type // may be nil if unknown

	// Err is the underlying error.
	Err error // may be nil
}

// coder is implemented by [jsontext.Encoder] or [jsontext.Decoder].
type coder interface {
	StackPointer() jsontext.Pointer
	Options() Options
}

// newInvalidFormatError constructs a SemanticError because
// the current type t cannot handle the provided options format.
// This function must be called before producing or consuming the next value.
//
// If [jsonflags.ReportErrorsWithLegacySemantics] is specified,
// then this automatically skips the next value when unmarshaling
// to ensure that the value is fully consumed.
func newInvalidFormatError(c coder, t reflect.Type) error {
	err := fmt.Errorf("invalid format flag %q", c.Options().(*jsonopts.Struct).Format)
	switch c := c.(type) {
	case *jsontext.Encoder:
		err = newMarshalErrorBefore(c, t, err)
	case *jsontext.Decoder:
		err = newUnmarshalErrorBeforeWithSkipping(c, t, err)
	}
	return err
}

// newMarshalErrorBefore wraps err in a SemanticError assuming that e
// is positioned right before the next token or value, which causes an error.
func newMarshalErrorBefore(e *jsontext.Encoder, t reflect.Type, err error) error {
	return &SemanticError{action: "marshal", GoType: t, Err: toUnexpectedEOF(err),
		ByteOffset:  e.OutputOffset() + int64(export.Encoder(e).CountNextDelimWhitespace()),
		JSONPointer: jsontext.Pointer(export.Encoder(e).AppendStackPointer(nil, +1))}
}

// newUnmarshalErrorBefore wraps err in a SemanticError assuming that d
// is positioned right before the next token or value, which causes an error.
// It does not record the next JSON kind as this error is used to indicate
// the receiving Go value is invalid to unmarshal into (and not a JSON error).
// However, if [jsonflags.ReportErrorsWithLegacySemantics] is specified,
// then it does record the next JSON kind for historical reporting reasons.
func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) error {
	var k jsontext.Kind
	if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		k = d.PeekKind()
	}
	return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err),
		ByteOffset:  d.InputOffset() + int64(export.Decoder(d).CountNextDelimWhitespace()),
		JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1)),
		JSONKind:    k}
}

// newUnmarshalErrorBeforeWithSkipping is like [newUnmarshalErrorBefore],
// but automatically skips the next value if
// [jsonflags.ReportErrorsWithLegacySemantics] is specified.
func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error {
	err = newUnmarshalErrorBefore(d, t, err)
	if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		if err2 := export.Decoder(d).SkipValue(); err2 != nil {
			return err2
		}
	}
	return err
}

// newUnmarshalErrorAfter wraps err in a SemanticError assuming that d
// is positioned right after the previous token or value, which caused an error.
func newUnmarshalErrorAfter(d *jsontext.Decoder, t reflect.Type, err error) error {
	tokOrVal := export.Decoder(d).PreviousTokenOrValue()
	byteOffset := d.InputOffset() - int64(len(tokOrVal))
	if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		// NOTE: In v1, the offset pointed to the end of the bad token or value.
		if k := jsontext.Value(tokOrVal).Kind(); k == '[' || k == '{' {
			byteOffset++ // add just the '[' or '{'
		} else {
			byteOffset += int64(len(tokOrVal))
		}
	}
	return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err),
		ByteOffset:  byteOffset,
		JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, -1)),
		JSONKind:    jsontext.Value(tokOrVal).Kind()}
}

// newUnmarshalErrorAfterWithValue wraps err in a SemanticError assuming that d
// is positioned right after the previous token or value, which caused an error.
// It also stores a copy of the last JSON value if it is a string or number.
func newUnmarshalErrorAfterWithValue(d *jsontext.Decoder, t reflect.Type, err error) error {
	serr := newUnmarshalErrorAfter(d, t, err).(*SemanticError)
	if serr.JSONKind == '"' || serr.JSONKind == '0' {
		serr.JSONValue = jsontext.Value(export.Decoder(d).PreviousTokenOrValue()).Clone()
	}
	return serr
}

// newUnmarshalErrorAfterWithSkipping is like [newUnmarshalErrorAfter],
// but automatically skips the remainder of the current value if
// [jsonflags.ReportErrorsWithLegacySemantics] is specified.
func newUnmarshalErrorAfterWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error {
	err = newUnmarshalErrorAfter(d, t, err)
	if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		if err2 := export.Decoder(d).SkipValueRemainder(); err2 != nil {
			return err2
		}
	}
	return err
}

// newSemanticErrorWithPosition wraps err in a SemanticError assuming that
// the error occurred at the provided depth, and length.
// If err is already a SemanticError, then position information is only
// injected if it is currently unpopulated.
//
// If the position is unpopulated, it is ambiguous where the error occurred
// in the user code, whether it was before or after the current position.
// For the byte offset, we assume that the error occurred before the last read
// token or value when decoding, or before the next value when encoding.
// For the JSON pointer, we point to the parent object or array unless
// we can be certain that it happened with an object member.
//
// This is used to annotate errors returned by user-provided
// v2 MarshalJSON or UnmarshalJSON methods or functions.
func newSemanticErrorWithPosition(c coder, t reflect.Type, prevDepth int, prevLength int64, err error) error {
	serr, _ := err.(*SemanticError)
	if serr == nil {
		serr = &SemanticError{Err: err}
	}
	serr.Err = toUnexpectedEOF(serr.Err)
	var currDepth int
	var currLength int64
	var coderState interface{ AppendStackPointer([]byte, int) []byte }
	var offset int64
	switch c := c.(type) {
	case *jsontext.Encoder:
		e := export.Encoder(c)
		serr.action = cmp.Or(serr.action, "marshal")
		currDepth, currLength = e.Tokens.DepthLength()
		offset = c.OutputOffset() + int64(export.Encoder(c).CountNextDelimWhitespace())
		coderState = e
	case *jsontext.Decoder:
		d := export.Decoder(c)
		serr.action = cmp.Or(serr.action, "unmarshal")
		currDepth, currLength = d.Tokens.DepthLength()
		tokOrVal := d.PreviousTokenOrValue()
		offset = c.InputOffset() - int64(len(tokOrVal))
		if (prevDepth == currDepth && prevLength == currLength) || len(tokOrVal) == 0 {
			// If no Read method was called in the user-defined method or
			// if the Peek method was called, then use the offset of the next value.
			offset = c.InputOffset() + int64(export.Decoder(c).CountNextDelimWhitespace())
		}
		coderState = d
	}
	serr.ByteOffset = cmp.Or(serr.ByteOffset, offset)
	if serr.JSONPointer == "" {
		where := 0 // default to ambiguous positioning
		switch {
		case prevDepth == currDepth && prevLength+0 == currLength:
			where = +1
		case prevDepth == currDepth && prevLength+1 == currLength:
			where = -1
		}
		serr.JSONPointer = jsontext.Pointer(coderState.AppendStackPointer(nil, where))
	}
	serr.GoType = cmp.Or(serr.GoType, t)
	return serr
}

// collapseSemanticErrors collapses double SemanticErrors at the outer levels
// into a single SemanticError by preserving the inner error,
// but prepending the ByteOffset and JSONPointer with the outer error.
//
// For example:
//
//	collapseSemanticErrors(&SemanticError{
//		ByteOffset:  len64(`[0,{"alpha":[0,1,`),
//		JSONPointer: "/1/alpha/2",
//		GoType:      reflect.TypeFor[outerType](),
//		Err: &SemanticError{
//			ByteOffset:  len64(`{"foo":"bar","fizz":[0,`),
//			JSONPointer: "/fizz/1",
//			GoType:      reflect.TypeFor[innerType](),
//			Err:         ...,
//		},
//	})
//
// results in:
//
//	&SemanticError{
//		ByteOffset:  len64(`[0,{"alpha":[0,1,`) + len64(`{"foo":"bar","fizz":[0,`),
//		JSONPointer: "/1/alpha/2" + "/fizz/1",
//		GoType:      reflect.TypeFor[innerType](),
//		Err:         ...,
//	}
//
// This is used to annotate errors returned by user-provided
// v1 MarshalJSON or UnmarshalJSON methods with precise position information
// if they themselves happened to return a SemanticError.
// Since MarshalJSON and UnmarshalJSON are not operating on the root JSON value,
// their positioning must be relative to the nested JSON value
// returned by UnmarshalJSON or passed to MarshalJSON.
// Therefore, we can construct an absolute position by concatenating
// the outer with the inner positions.
//
// Note that we do not use collapseSemanticErrors with user-provided functions
// that take in an [jsontext.Encoder] or [jsontext.Decoder] since they contain
// methods to report position relative to the root JSON value.
// We assume user-constructed errors are correctly precise about position.
func collapseSemanticErrors(err error) error {
	if serr1, ok := err.(*SemanticError); ok {
		if serr2, ok := serr1.Err.(*SemanticError); ok {
			serr2.ByteOffset = serr1.ByteOffset + serr2.ByteOffset
			serr2.JSONPointer = serr1.JSONPointer + serr2.JSONPointer
			*serr1 = *serr2
		}
	}
	return err
}

func wrapErrUnsupported(err error, what string) error {
	if errors.Is(err, errors.ErrUnsupported) {
		return errors.New(what + " may not return errors.ErrUnsupported")
	}
	return err
}

// errorModalVerb is a modal verb like "cannot" or "unable to".
//
// Once per process, Hyrum-proof the error message by deliberately
// switching between equivalent renderings of the same error message.
// The randomization is tied to the Hyrum-proofing already applied
// on map iteration in Go.
var errorModalVerb = sync.OnceValue(func() string {
	for phrase := range map[string]struct{}{"cannot": {}, "unable to": {}} {
		return phrase // use whichever phrase we get in the first iteration
	}
	return ""
})

func (e *SemanticError) Error() string {
	var sb strings.Builder
	sb.WriteString(errorPrefix)
	sb.WriteString(errorModalVerb())

	// Format action.
	var preposition string
	switch e.action {
	case "marshal":
		sb.WriteString(" marshal")
		preposition = " from"
	case "unmarshal":
		sb.WriteString(" unmarshal")
		preposition = " into"
	default:
		sb.WriteString(" handle")
		preposition = " with"
	}

	// Format JSON kind.
	switch e.JSONKind {
	case 'n':
		sb.WriteString(" JSON null")
	case 'f', 't':
		sb.WriteString(" JSON boolean")
	case '"':
		sb.WriteString(" JSON string")
	case '0':
		sb.WriteString(" JSON number")
	case '{', '}':
		sb.WriteString(" JSON object")
	case '[', ']':
		sb.WriteString(" JSON array")
	default:
		if e.action == "" {
			preposition = ""
		}
	}
	if len(e.JSONValue) > 0 && len(e.JSONValue) < 100 {
		sb.WriteByte(' ')
		sb.Write(e.JSONValue)
	}

	// Format Go type.
	if e.GoType != nil {
		typeString := e.GoType.String()
		if len(typeString) > 100 {
			// An excessively long type string most likely occurs for
			// an anonymous struct declaration with many fields.
			// Reduce the noise by just printing the kind,
			// and optionally prepending it with the package name
			// if the struct happens to include an unexported field.
			typeString = e.GoType.Kind().String()
			if e.GoType.Kind() == reflect.Struct && e.GoType.Name() == "" {
				for i := range e.GoType.NumField() {
					if pkgPath := e.GoType.Field(i).PkgPath; pkgPath != "" {
						typeString = pkgPath[strings.LastIndexByte(pkgPath, '/')+len("/"):] + ".struct"
						break
					}
				}
			}
		}
		sb.WriteString(preposition)
		sb.WriteString(" Go ")
		sb.WriteString(typeString)
	}

	// Special handling for unknown names.
	if e.Err == ErrUnknownName || e.Err == errAmbiguousName {
		sb.WriteString(": ")
		sb.WriteString(e.Err.Error())
		sb.WriteString(" ")
		sb.WriteString(strconv.Quote(e.JSONPointer.LastToken()))
		if parent := e.JSONPointer.Parent(); parent != "" {
			sb.WriteString(" within ")
			sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(parent), 100)))
		}
		return sb.String()
	}

	// Format where.
	// Avoid printing if it overlaps with a wrapped SyntacticError.
	switch serr, _ := e.Err.(*jsontext.SyntacticError); {
	case e.JSONPointer != "":
		if serr == nil || !e.JSONPointer.Contains(serr.JSONPointer) {
			sb.WriteString(" within ")
			sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(e.JSONPointer), 100)))
		}
	case e.ByteOffset > 0:
		if serr == nil || !(e.ByteOffset <= serr.ByteOffset) {
			sb.WriteString(" after offset ")
			sb.WriteString(strconv.FormatInt(e.ByteOffset, 10))
		}
	}

	// Format underlying error.
	if e.Err != nil {
		errString := e.Err.Error()
		if isSyntacticError(e.Err) {
			errString = strings.TrimPrefix(errString, "jsontext: ")
		}
		sb.WriteString(": ")
		sb.WriteString(errString)
	}

	return sb.String()
}

func (e *SemanticError) Unwrap() error {
	return e.Err
}

func newDuplicateNameError(ptr jsontext.Pointer, quotedName []byte, offset int64) error {
	if quotedName != nil {
		name, _ := jsonwire.AppendUnquote(nil, quotedName)
		ptr = ptr.AppendToken(string(name))
	}
	return &jsontext.SyntacticError{
		ByteOffset:  offset,
		JSONPointer: ptr,
		Err:         jsontext.ErrDuplicateName,
	}
}

// toUnexpectedEOF converts [io.EOF] to [io.ErrUnexpectedEOF].
func toUnexpectedEOF(err error) error {
	if err == io.EOF {
		return io.ErrUnexpectedEOF
	}
	return err
}
