// Copyright 2024 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 (
	"fmt"
	"reflect"
	"strconv"
	"strings"

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

// Inject functionality into v2 to properly handle v1 types.
func init() {
	internal.TransformMarshalError = transformMarshalError
	internal.TransformUnmarshalError = transformUnmarshalError
	internal.NewMarshalerError = func(val any, err error, funcName string) error {
		return &MarshalerError{reflect.TypeOf(val), err, funcName}
	}

	internal.NewRawNumber = func() any { return new(Number) }
	internal.RawNumberOf = func(b []byte) any { return Number(b) }
}

func transformMarshalError(root any, err error) error {
	// Historically, errors returned from Marshal methods were wrapped
	// in a [MarshalerError]. This is directly performed by the v2 package
	// via the injected [internal.NewMarshalerError] constructor
	// while operating under [ReportErrorsWithLegacySemantics].
	// Note that errors from a Marshal method were always wrapped,
	// even if wrapped for multiple layers.
	if err, ok := err.(*jsonv2.SemanticError); err != nil {
		if err.Err == nil {
			// Historically, this was only reported for unserializable types
			// like complex numbers, channels, functions, and unsafe.Pointers.
			return &UnsupportedTypeError{Type: err.GoType}
		} else {
			// Historically, this was only reported for NaN or ±Inf values
			// and cycles detected in the value.
			// The Value field used to be populated with the reflect.Value,
			// but this is no longer supported.
			errStr := err.Err.Error()
			if err.Err == internal.ErrCycle && err.GoType != nil {
				errStr += " via " + err.GoType.String()
			}
			errStr = strings.TrimPrefix(errStr, "unsupported value: ")
			return &UnsupportedValueError{Str: errStr}
		}
	} else if ok {
		return (*UnsupportedValueError)(nil)
	}
	if err, _ := err.(*MarshalerError); err != nil {
		err.Err = transformSyntacticError(err.Err)
		return err
	}
	return transformSyntacticError(err)
}

func transformUnmarshalError(root any, err error) error {
	// Historically, errors from Unmarshal methods were never wrapped and
	// returned verbatim while operating under [ReportErrorsWithLegacySemantics].
	if err, ok := err.(*jsonv2.SemanticError); err != nil {
		if err.Err == internal.ErrNonNilReference {
			return &InvalidUnmarshalError{err.GoType}
		}
		if err.Err == jsonv2.ErrUnknownName {
			return fmt.Errorf("json: unknown field %q", err.JSONPointer.LastToken())
		}
		if err.Err == internal.ErrNilInterface {
			err.Err = nil // non-descriptive for historical reasons
		}

		// Historically, UnmarshalTypeError has always been inconsistent
		// about how it reported position information.
		//
		// The Struct field now points to the root type,
		// rather than some intermediate struct in the path.
		// This better matches the original intent of the field based
		// on how the Error message was formatted.
		//
		// For a representation closer to the historical representation,
		// we switch the '/'-delimited representation of a JSON pointer
		// to use a '.'-delimited representation. This may be ambiguous,
		// but the prior representation was always ambiguous as well.
		// Users that care about precise positions should use v2 errors
		// by disabling [ReportErrorsWithLegacySemantics].
		//
		// The introduction of an Err field is new to the v1-to-v2 migration
		// and allows us to preserve stronger error information
		// that may be surfaced by the v2 package.
		//
		// See https://go.dev/issue/43126
		var value string
		switch err.JSONKind {
		case 'n', '"', '0':
			value = err.JSONKind.String()
		case 'f', 't':
			value = "bool"
		case '[', ']':
			value = "array"
		case '{', '}':
			value = "object"
		}
		if len(err.JSONValue) > 0 {
			isStrconvError := err.Err == strconv.ErrRange || err.Err == strconv.ErrSyntax
			isNumericKind := func(t reflect.Type) bool {
				if t == nil {
					return false
				}
				switch t.Kind() {
				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
					reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
					reflect.Float32, reflect.Float64:
					return true
				}
				return false
			}
			if isStrconvError && isNumericKind(err.GoType) {
				value = "number"
				if err.JSONKind == '"' {
					err.JSONValue, _ = jsontext.AppendUnquote(nil, err.JSONValue)
				}
				err.Err = nil
			}
			value += " " + string(err.JSONValue)
		}
		var rootName string
		if t := reflect.TypeOf(root); t != nil && err.JSONPointer != "" {
			if t.Kind() == reflect.Pointer {
				t = t.Elem()
			}
			rootName = t.Name()
		}
		fieldPath := string(err.JSONPointer)
		fieldPath = strings.TrimPrefix(fieldPath, "/")
		fieldPath = strings.ReplaceAll(fieldPath, "/", ".")
		return &UnmarshalTypeError{
			Value:  value,
			Type:   err.GoType,
			Offset: err.ByteOffset,
			Struct: rootName,
			Field:  fieldPath,
			Err:    transformSyntacticError(err.Err),
		}
	} else if ok {
		return (*UnmarshalTypeError)(nil)
	}
	return transformSyntacticError(err)
}
