// 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 jsontext

import (
	"bytes"
	"io"
	"strconv"

	"encoding/json/internal/jsonwire"
)

const errorPrefix = "jsontext: "

type ioError struct {
	action string // either "read" or "write"
	err    error
}

func (e *ioError) Error() string {
	return errorPrefix + e.action + " error: " + e.err.Error()
}
func (e *ioError) Unwrap() error {
	return e.err
}

type numError struct {
	accessor string // either "Int", "Uint", or "Float"
	value    string // e.g., "1e1000"
	err      error  // either [strconv.ErrSyntax] or [strconv.ErrRange]
}

func (e *numError) Error() string {
	return "jsontext.Token(" + e.value + ")." + e.accessor + " error: " + e.err.Error()
}
func (e *numError) Unwrap() error {
	return e.err
}

// SyntacticError is a description of a syntactic error that occurred when
// encoding or decoding JSON according to the grammar.
//
// The contents of this error as produced by this package may change over time.
type SyntacticError struct {
	requireKeyedLiterals
	nonComparable

	// ByteOffset indicates that an error occurred 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 Pointer

	// Err is the underlying error.
	Err error
}

// wrapSyntacticError wraps an error and annotates it with a precise location
// using the provided [encoderState] or [decoderState].
// If err is an [ioError] or [io.EOF], then it is not wrapped.
//
// It takes a relative offset pos that can be resolved into
// an absolute offset using state.offsetAt.
//
// It takes a where that specify how the JSON pointer is derived.
// If the underlying error is a [pointerSuffixError],
// then the suffix is appended to the derived pointer.
func wrapSyntacticError(state interface {
	offsetAt(pos int) int64
	AppendStackPointer(b []byte, where int) []byte
}, err error, pos, where int) error {
	if _, ok := err.(*ioError); err == io.EOF || ok {
		return err
	}
	offset := state.offsetAt(pos)
	ptr := state.AppendStackPointer(nil, where)
	if serr, ok := err.(*pointerSuffixError); ok {
		ptr = serr.appendPointer(ptr)
		err = serr.error
	}
	if d, ok := state.(*decoderState); ok && err == errMismatchDelim {
		where := "at start of value"
		if len(d.Tokens.Stack) > 0 && d.Tokens.Last.Length() > 0 {
			switch {
			case d.Tokens.Last.isArray():
				where = "after array element (expecting ',' or ']')"
				ptr = []byte(Pointer(ptr).Parent()) // problem is with parent array
			case d.Tokens.Last.isObject():
				where = "after object value (expecting ',' or '}')"
				ptr = []byte(Pointer(ptr).Parent()) // problem is with parent object
			}
		}
		err = jsonwire.NewInvalidCharacterError(d.buf[pos:], where)
	}
	return &SyntacticError{ByteOffset: offset, JSONPointer: Pointer(ptr), Err: err}
}

func (e *SyntacticError) Error() string {
	pointer := e.JSONPointer
	offset := e.ByteOffset
	b := []byte(errorPrefix)
	if e.Err != nil {
		b = append(b, e.Err.Error()...)
		if e.Err == ErrDuplicateName {
			b = strconv.AppendQuote(append(b, ' '), pointer.LastToken())
			pointer = pointer.Parent()
			offset = 0 // not useful to print offset for duplicate names
		}
	} else {
		b = append(b, "syntactic error"...)
	}
	if pointer != "" {
		b = strconv.AppendQuote(append(b, " within "...), jsonwire.TruncatePointer(string(pointer), 100))
	}
	if offset > 0 {
		b = strconv.AppendInt(append(b, " after offset "...), offset, 10)
	}
	return string(b)
}

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

// pointerSuffixError represents a JSON pointer suffix to be appended
// to [SyntacticError.JSONPointer]. It is an internal error type
// used within this package and does not appear in the public API.
//
// This type is primarily used to annotate errors in Encoder.WriteValue
// and Decoder.ReadValue with precise positions.
// At the time WriteValue or ReadValue is called, a JSON pointer to the
// upcoming value can be constructed using the Encoder/Decoder state.
// However, tracking pointers within values during normal operation
// would incur a performance penalty in the error-free case.
//
// To provide precise error locations without this overhead,
// the error is wrapped with object names or array indices
// as the call stack is popped when an error occurs.
// Since this happens in reverse order, pointerSuffixError holds
// the pointer in reverse and is only later reversed when appending to
// the pointer prefix.
//
// For example, if the encoder is at "/alpha/bravo/charlie"
// and an error occurs in WriteValue at "/xray/yankee/zulu", then
// the final pointer should be "/alpha/bravo/charlie/xray/yankee/zulu".
//
// As pointerSuffixError is populated during the error return path,
// it first contains "/zulu", then "/zulu/yankee",
// and finally "/zulu/yankee/xray".
// These tokens are reversed and concatenated to "/alpha/bravo/charlie"
// to form the full pointer.
type pointerSuffixError struct {
	error

	// reversePointer is a JSON pointer, but with each token in reverse order.
	reversePointer []byte
}

// wrapWithObjectName wraps err with a JSON object name access,
// which must be a valid quoted JSON string.
func wrapWithObjectName(err error, quotedName []byte) error {
	serr, _ := err.(*pointerSuffixError)
	if serr == nil {
		serr = &pointerSuffixError{error: err}
	}
	name := jsonwire.UnquoteMayCopy(quotedName, false)
	serr.reversePointer = appendEscapePointerName(append(serr.reversePointer, '/'), name)
	return serr
}

// wrapWithArrayIndex wraps err with a JSON array index access.
func wrapWithArrayIndex(err error, index int64) error {
	serr, _ := err.(*pointerSuffixError)
	if serr == nil {
		serr = &pointerSuffixError{error: err}
	}
	serr.reversePointer = strconv.AppendUint(append(serr.reversePointer, '/'), uint64(index), 10)
	return serr
}

// appendPointer appends the path encoded in e to the end of pointer.
func (e *pointerSuffixError) appendPointer(pointer []byte) []byte {
	// Copy each token in reversePointer to the end of pointer in reverse order.
	// Double reversal means that the appended suffix is now in forward order.
	bi, bo := e.reversePointer, pointer
	for len(bi) > 0 {
		i := bytes.LastIndexByte(bi, '/')
		bi, bo = bi[:i], append(bo, bi[i:]...)
	}
	return bo
}
