// Copyright 2023 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"

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

// Options configure [Marshal], [MarshalWrite], [MarshalEncode],
// [Unmarshal], [UnmarshalRead], and [UnmarshalDecode] with specific features.
// Each function takes in a variadic list of options, where properties
// set in later options override the value of previously set properties.
//
// The Options type is identical to [encoding/json.Options] and
// [encoding/json/jsontext.Options]. Options from the other packages can
// be used interchangeably with functionality in this package.
//
// Options represent either a singular option or a set of options.
// It can be functionally thought of as a Go map of option properties
// (even though the underlying implementation avoids Go maps for performance).
//
// The constructors (e.g., [Deterministic]) return a singular option value:
//
//	opt := Deterministic(true)
//
// which is analogous to creating a single entry map:
//
//	opt := Options{"Deterministic": true}
//
// [JoinOptions] composes multiple options values together:
//
//	out := JoinOptions(opts...)
//
// which is analogous to making a new map and copying the options over:
//
//	out := make(Options)
//	for _, m := range opts {
//		for k, v := range m {
//			out[k] = v
//		}
//	}
//
// [GetOption] looks up the value of an options parameter:
//
//	v, ok := GetOption(opts, Deterministic)
//
// which is analogous to a Go map lookup:
//
//	v, ok := Options["Deterministic"]
//
// There is a single Options type, which is used with both marshal and unmarshal.
// Some options affect both operations, while others only affect one operation:
//
//   - [StringifyNumbers] affects marshaling and unmarshaling
//   - [Deterministic] affects marshaling only
//   - [FormatNilSliceAsNull] affects marshaling only
//   - [FormatNilMapAsNull] affects marshaling only
//   - [OmitZeroStructFields] affects marshaling only
//   - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling
//   - [RejectUnknownMembers] affects unmarshaling only
//   - [WithMarshalers] affects marshaling only
//   - [WithUnmarshalers] affects unmarshaling only
//
// Options that do not affect a particular operation are ignored.
type Options = jsonopts.Options

// JoinOptions coalesces the provided list of options into a single Options.
// Properties set in later options override the value of previously set properties.
func JoinOptions(srcs ...Options) Options {
	var dst jsonopts.Struct
	dst.Join(srcs...)
	return &dst
}

// GetOption returns the value stored in opts with the provided setter,
// reporting whether the value is present.
// If not present, the returned value is the zero value for type T.
//
// Example usage:
//
//	v, ok := json.GetOption(opts, json.Deterministic)
//
// Options are most commonly introspected to alter the JSON representation of
// [MarshalerTo.MarshalJSONTo] and [UnmarshalerFrom.UnmarshalJSONFrom] methods, and
// [MarshalToFunc] and [UnmarshalFromFunc] functions.
// In such cases, the presence bit should generally be ignored.
func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
	return jsonopts.GetOption(opts, setter)
}

// DefaultOptionsV2 is the full set of all options that define v2 semantics.
// It is equivalent to the set of options in [encoding/json.DefaultOptionsV1]
// all being set to false. All other options are not present.
func DefaultOptionsV2() Options {
	return &jsonopts.DefaultOptionsV2
}

// StringifyNumbers specifies that types that would normally be
// encoded as a JSON number to instead be encoded as a JSON string
// containing the equivalent JSON number value.
// When unmarshaling, the value is parsed from a JSON string
// containing the JSON number without any surrounding whitespace.
//
// When the `string` tag option is specified on a Go struct field,
// this option is applied for the top-level JSON value for that field.
// Unless StringifyNumbers was applied globally, the option does not
// recursively apply to nested JSON numbers within a JSON object or array.
// A Go type with custom marshal/unmarshal that represents a JSON number
// should respect the StringifyNumbers option and if specified
// serialize as a JSON number within a JSON string.
//
// According to RFC 8259, section 6, a JSON implementation may choose to
// limit the representation of a JSON number to an IEEE 754 binary64 value.
// This may cause decoders to lose precision for int64 and uint64 types.
// Quoting JSON numbers as a JSON string preserves the exact precision.
//
// This affects either marshaling or unmarshaling.
func StringifyNumbers(v bool) Options {
	if v {
		return jsonflags.StringifyNumbers | 1
	} else {
		return jsonflags.StringifyNumbers | 0
	}
}

// Deterministic specifies that the same input value will be serialized
// as the exact same output bytes. Different processes of
// the same program will serialize equal values to the same bytes,
// but different versions of the same program are not guaranteed
// to produce the exact same sequence of bytes.
//
// This only affects marshaling and is ignored when unmarshaling.
func Deterministic(v bool) Options {
	if v {
		return jsonflags.Deterministic | 1
	} else {
		return jsonflags.Deterministic | 0
	}
}

// FormatNilSliceAsNull specifies that a nil Go slice should marshal as a
// JSON null instead of the default representation as an empty JSON array
// (or an empty JSON string in the case of ~[]byte).
//
// This only affects marshaling and is ignored when unmarshaling.
func FormatNilSliceAsNull(v bool) Options {
	if v {
		return jsonflags.FormatNilSliceAsNull | 1
	} else {
		return jsonflags.FormatNilSliceAsNull | 0
	}
}

// FormatNilMapAsNull specifies that a nil Go map should marshal as a
// JSON null instead of the default representation as an empty JSON object.
//
// This only affects marshaling and is ignored when unmarshaling.
func FormatNilMapAsNull(v bool) Options {
	if v {
		return jsonflags.FormatNilMapAsNull | 1
	} else {
		return jsonflags.FormatNilMapAsNull | 0
	}
}

// OmitZeroStructFields specifies that a Go struct should marshal in such a way
// that all struct fields that are zero are omitted from the marshaled output
// if the value is zero as determined by the "IsZero() bool" method if present,
// otherwise based on whether the field is the zero Go value.
// This is semantically equivalent to specifying the `omitzero` tag option
// on every field in a Go struct.
//
// This only affects marshaling and is ignored when unmarshaling.
func OmitZeroStructFields(v bool) Options {
	if v {
		return jsonflags.OmitZeroStructFields | 1
	} else {
		return jsonflags.OmitZeroStructFields | 0
	}
}

// MatchCaseInsensitiveNames specifies that JSON object members are matched
// against Go struct fields using a case-insensitive match of the name.
// If a name matches multiple fields, it chooses the field with an exact
// match of the name, otherwise it reports an error.
// Go struct fields explicitly marked with `case:strict` or `case:ignore`
// always use case-sensitive (or case-insensitive) name matching,
// regardless of the value of this option.
//
// This affects either marshaling or unmarshaling.
//
// By matching names in a case-insensitive manner, it also affects the detection
// of duplicate names (assuming [jsontext.AllowDuplicateNames] is false) since
// variations of the same name may match the same Go struct field.
// For example, when unmarshaling, the names "foo" and "Foo" may both
// match the same Go struct field and therefore be considered a duplicate name.
// When marshaling, normally it is impossible for any two Go struct fields to
// serialize in a way where they unmarshal into the same Go struct field
// since they all have unique exact names.
// However, with the use of an embedded fallback, it is possible for the
// embedded fallback to contain a name that also matches the name for
// a Go struct field, resulting in a duplicate name error.
func MatchCaseInsensitiveNames(v bool) Options {
	if v {
		return jsonflags.MatchCaseInsensitiveNames | 1
	} else {
		return jsonflags.MatchCaseInsensitiveNames | 0
	}
}

// RejectUnknownMembers specifies that unknown members should be rejected
// when unmarshaling a JSON object.
//
// This only affects unmarshaling and is ignored when marshaling.
func RejectUnknownMembers(v bool) Options {
	if v {
		return jsonflags.RejectUnknownMembers | 1
	} else {
		return jsonflags.RejectUnknownMembers | 0
	}
}

// WithMarshalers specifies a list of type-specific marshalers to use,
// which can be used to override the default marshal behavior for values
// of particular types.
//
// This only affects marshaling and is ignored when unmarshaling.
func WithMarshalers(v *Marshalers) Options {
	return (*marshalersOption)(v)
}

// WithUnmarshalers specifies a list of type-specific unmarshalers to use,
// which can be used to override the default unmarshal behavior for values
// of particular types.
//
// This only affects unmarshaling and is ignored when marshaling.
func WithUnmarshalers(v *Unmarshalers) Options {
	return (*unmarshalersOption)(v)
}

// These option types are declared here instead of "jsonopts"
// to avoid a dependency on "reflect" from "jsonopts".
type (
	marshalersOption   Marshalers
	unmarshalersOption Unmarshalers
)

func (*marshalersOption) JSONOptions(internal.NotForPublicUse)   {}
func (*unmarshalersOption) JSONOptions(internal.NotForPublicUse) {}

// Inject support into "jsonopts" to handle these types.
func init() {
	jsonopts.GetUnknownOption = func(src jsonopts.Struct, zero jsonopts.Options) (any, bool) {
		switch zero.(type) {
		case *marshalersOption:
			if !src.Flags.Has(jsonflags.Marshalers) {
				return (*Marshalers)(nil), false
			}
			return src.Marshalers.(*Marshalers), true
		case *unmarshalersOption:
			if !src.Flags.Has(jsonflags.Unmarshalers) {
				return (*Unmarshalers)(nil), false
			}
			return src.Unmarshalers.(*Unmarshalers), true
		default:
			panic(fmt.Sprintf("unknown option %T", zero))
		}
	}
	jsonopts.JoinUnknownOption = func(dst jsonopts.Struct, src jsonopts.Options) jsonopts.Struct {
		switch src := src.(type) {
		case *marshalersOption:
			dst.Flags.Set(jsonflags.Marshalers | 1)
			dst.Marshalers = (*Marshalers)(src)
		case *unmarshalersOption:
			dst.Flags.Set(jsonflags.Unmarshalers | 1)
			dst.Unmarshalers = (*Unmarshalers)(src)
		default:
			panic(fmt.Sprintf("unknown option %T", src))
		}
		return dst
	}
}
