// Copyright 2022 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_test

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/netip"
	"os"
	"reflect"
	"strconv"
	"strings"
	"sync/atomic"
	"time"

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

// If a type implements [encoding.TextMarshaler] and/or [encoding.TextUnmarshaler],
// then the MarshalText and UnmarshalText methods are used to encode/decode
// the value to/from a JSON string.
func Example_textMarshal() {
	// Round-trip marshal and unmarshal a hostname map where the netip.Addr type
	// implements both encoding.TextMarshaler and encoding.TextUnmarshaler.
	want := map[netip.Addr]string{
		netip.MustParseAddr("192.168.0.100"): "carbonite",
		netip.MustParseAddr("192.168.0.101"): "obsidian",
		netip.MustParseAddr("192.168.0.102"): "diamond",
	}
	b, err := json.Marshal(&want, json.Deterministic(true))
	if err != nil {
		log.Fatal(err)
	}
	var got map[netip.Addr]string
	err = json.Unmarshal(b, &got)
	if err != nil {
		log.Fatal(err)
	}

	// Sanity check.
	if !reflect.DeepEqual(got, want) {
		log.Fatalf("roundtrip mismatch: got %v, want %v", got, want)
	}

	// Indent output for readability.
	v := jsontext.Value(b)
	v.Indent()
	fmt.Println(string(v))

	// Output:
	// {
	// 	"192.168.0.100": "carbonite",
	// 	"192.168.0.101": "obsidian",
	// 	"192.168.0.102": "diamond"
	// }
}

// By default, JSON object names for Go struct fields are derived from
// the Go field name, but may be specified in the `json` tag.
// Due to JSON's heritage in JavaScript, the most common naming convention
// used for JSON object names is camelCase.
func Example_fieldNames() {
	var value struct {
		// This field is explicitly ignored with the special "-" name.
		Ignored any `json:"-"`
		// No JSON name is not provided, so the Go field name is used.
		GoName any
		// A JSON name is provided without any special characters.
		JSONName any `json:"jsonName"`
		// No JSON name is not provided, so the Go field name is used.
		Option any `json:",case:ignore"`
		// An unexported field is always ignored.
		unexported any
	}

	b, err := json.Marshal(value)
	if err != nil {
		log.Fatal(err)
	}

	// Indent output for readability.
	v := jsontext.Value(b)
	v.Indent()
	fmt.Println(string(v))

	// Output:
	// {
	// 	"GoName": null,
	// 	"jsonName": null,
	// 	"Option": null
	// }
}

// Unmarshal matches JSON object names with Go struct fields using
// a case-sensitive match, but can be configured to use a case-insensitive
// match with the "case:ignore" option. This permits unmarshaling from inputs
// that use naming conventions such as camelCase, snake_case, or kebab-case.
func Example_caseSensitivity() {
	// JSON input using various naming conventions.
	const input = `[
		{"firstname": true},
		{"firstName": true},
		{"FirstName": true},
		{"FIRSTNAME": true},
		{"first_name": true},
		{"FIRST_NAME": true},
		{"first-name": true},
		{"FIRST-NAME": true},
		{"unknown": true}
	]`

	// Without "case:ignore", Unmarshal looks for an exact match.
	var caseStrict []struct {
		X bool `json:"firstName"`
	}
	if err := json.Unmarshal([]byte(input), &caseStrict); err != nil {
		log.Fatal(err)
	}
	fmt.Println(caseStrict) // exactly 1 match found

	// With "case:ignore", Unmarshal looks first for an exact match,
	// then for a case-insensitive match if none found.
	var caseIgnore []struct {
		X bool `json:"firstName,case:ignore"`
	}
	if err := json.Unmarshal([]byte(input), &caseIgnore); err != nil {
		log.Fatal(err)
	}
	fmt.Println(caseIgnore) // 8 matches found

	// Output:
	// [{false} {true} {false} {false} {false} {false} {false} {false} {false}]
	// [{true} {true} {true} {true} {true} {true} {true} {true} {false}]
}

// Go struct fields can be omitted from the output depending on either
// the input Go value or the output JSON encoding of the value.
// The "omitzero" option omits a field if it is the zero Go value or
// implements a "IsZero() bool" method that reports true.
// The "omitempty" option omits a field if it encodes as an empty JSON value,
// which we define as a JSON null or empty JSON string, object, or array.
// In many cases, the behavior of "omitzero" and "omitempty" are equivalent.
// If both provide the desired effect, then using "omitzero" is preferred.
func Example_omitFields() {
	type MyStruct struct {
		Foo string `json:",omitzero"`
		Bar []int  `json:",omitempty"`
		// Both "omitzero" and "omitempty" can be specified together,
		// in which case the field is omitted if either would take effect.
		// This omits the Baz field either if it is a nil pointer or
		// if it would have encoded as an empty JSON object.
		Baz *MyStruct `json:",omitzero,omitempty"`
	}

	// Demonstrate behavior of "omitzero".
	b, err := json.Marshal(struct {
		Bool         bool        `json:",omitzero"`
		Int          int         `json:",omitzero"`
		String       string      `json:",omitzero"`
		Time         time.Time   `json:",omitzero"`
		Addr         netip.Addr  `json:",omitzero"`
		Struct       MyStruct    `json:",omitzero"`
		SliceNil     []int       `json:",omitzero"`
		Slice        []int       `json:",omitzero"`
		MapNil       map[int]int `json:",omitzero"`
		Map          map[int]int `json:",omitzero"`
		PointerNil   *string     `json:",omitzero"`
		Pointer      *string     `json:",omitzero"`
		InterfaceNil any         `json:",omitzero"`
		Interface    any         `json:",omitzero"`
	}{
		// Bool is omitted since false is the zero value for a Go bool.
		Bool: false,
		// Int is omitted since 0 is the zero value for a Go int.
		Int: 0,
		// String is omitted since "" is the zero value for a Go string.
		String: "",
		// Time is omitted since time.Time.IsZero reports true.
		Time: time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
		// Addr is omitted since netip.Addr{} is the zero value for a Go struct.
		Addr: netip.Addr{},
		// Struct is NOT omitted since it is not the zero value for a Go struct.
		Struct: MyStruct{Bar: []int{}, Baz: new(MyStruct)},
		// SliceNil is omitted since nil is the zero value for a Go slice.
		SliceNil: nil,
		// Slice is NOT omitted since []int{} is not the zero value for a Go slice.
		Slice: []int{},
		// MapNil is omitted since nil is the zero value for a Go map.
		MapNil: nil,
		// Map is NOT omitted since map[int]int{} is not the zero value for a Go map.
		Map: map[int]int{},
		// PointerNil is omitted since nil is the zero value for a Go pointer.
		PointerNil: nil,
		// Pointer is NOT omitted since new(string) is not the zero value for a Go pointer.
		Pointer: new(string),
		// InterfaceNil is omitted since nil is the zero value for a Go interface.
		InterfaceNil: nil,
		// Interface is NOT omitted since (*string)(nil) is not the zero value for a Go interface.
		Interface: (*string)(nil),
	})
	if err != nil {
		log.Fatal(err)
	}
	// Indent output for readability.
	v := jsontext.Value(b)
	v.Indent()
	fmt.Println("OmitZero:", string(v)) // outputs "Struct", "Slice", "Map", "Pointer", and "Interface"

	// Demonstrate behavior of "omitempty".
	b, err = json.Marshal(struct {
		Bool         bool        `json:",omitempty"`
		Int          int         `json:",omitempty"`
		String       string      `json:",omitempty"`
		Time         time.Time   `json:",omitempty"`
		Addr         netip.Addr  `json:",omitempty"`
		Struct       MyStruct    `json:",omitempty"`
		Slice        []int       `json:",omitempty"`
		Map          map[int]int `json:",omitempty"`
		PointerNil   *string     `json:",omitempty"`
		Pointer      *string     `json:",omitempty"`
		InterfaceNil any         `json:",omitempty"`
		Interface    any         `json:",omitempty"`
	}{
		// Bool is NOT omitted since false is not an empty JSON value.
		Bool: false,
		// Int is NOT omitted since 0 is not a empty JSON value.
		Int: 0,
		// String is omitted since "" is an empty JSON string.
		String: "",
		// Time is NOT omitted since this encodes as a non-empty JSON string.
		Time: time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
		// Addr is omitted since this encodes as an empty JSON string.
		Addr: netip.Addr{},
		// Struct is omitted since {} is an empty JSON object.
		Struct: MyStruct{Bar: []int{}, Baz: new(MyStruct)},
		// Slice is omitted since [] is an empty JSON array.
		Slice: []int{},
		// Map is omitted since {} is an empty JSON object.
		Map: map[int]int{},
		// PointerNil is omitted since null is an empty JSON value.
		PointerNil: nil,
		// Pointer is omitted since "" is an empty JSON string.
		Pointer: new(string),
		// InterfaceNil is omitted since null is an empty JSON value.
		InterfaceNil: nil,
		// Interface is omitted since null is an empty JSON value.
		Interface: (*string)(nil),
	})
	if err != nil {
		log.Fatal(err)
	}
	// Indent output for readability.
	v = jsontext.Value(b)
	v.Indent()
	fmt.Println("OmitEmpty:", string(v)) // outputs "Bool", "Int", and "Time"

	// Output:
	// OmitZero: {
	// 	"Struct": {},
	// 	"Slice": [],
	// 	"Map": {},
	// 	"Pointer": "",
	// 	"Interface": null
	// }
	// OmitEmpty: {
	// 	"Bool": false,
	// 	"Int": 0,
	// 	"Time": "0001-01-01T00:00:00Z"
	// }
}

// JSON objects can be embedded within a parent object similar to
// how Go structs can be embedded within a parent struct.
// The JSON embedding rules are similar to those of Go embedding,
// but operates upon the JSON namespace.
func Example_embeddedFields() {
	// Base is embedded within Container.
	type Base struct {
		// ID is promoted into the JSON object for Container.
		ID string
		// Type is ignored due to presence of Container.Type.
		Type string
		// Time cancels out with Container.Embed.Time.
		Time time.Time
	}
	// Other is embedded within Container.
	type Other struct{ Cost float64 }
	// Container embeds Base and Other.
	type Container struct {
		// Base is an embedded struct and is implicitly JSON embedded.
		Base
		// Type takes precedence over Base.Type.
		Type int
		// Embed is a named Go field, but is explicitly JSON embedded.
		Embed struct {
			// User is promoted into the JSON object for Container.
			User string
			// Time cancels out with Base.Time.
			Time string
		} `json:",embed"`
		// ID does not conflict with Base.ID since the JSON name is different.
		ID string `json:"uuid"`
		// Other is not JSON embedded since it has an explicit JSON name.
		Other `json:"other"`
	}

	// Format an empty Container to show what fields are JSON serializable.
	var input Container
	b, err := json.Marshal(&input)
	if err != nil {
		log.Fatal(err)
	}
	// Indent output for readability.
	v := jsontext.Value(b)
	v.Indent()
	fmt.Println(string(v))

	// Output:
	// {
	// 	"ID": "",
	// 	"Type": 0,
	// 	"User": "",
	// 	"uuid": "",
	// 	"other": {
	// 		"Cost": 0
	// 	}
	// }
}

// When implementing HTTP endpoints, it is common to be operating with an
// [io.Reader] and an [io.Writer]. The [MarshalWrite] and [UnmarshalRead] functions
// assist in operating on such input/output types.
// [UnmarshalRead] reads the entirety of the [io.Reader] to ensure that [io.EOF]
// is encountered without any unexpected bytes after the top-level JSON value.
func Example_serveHTTP() {
	// Some global state maintained by the server.
	var n int64

	// The "add" endpoint accepts a POST request with a JSON object
	// containing a number to atomically add to the server's global counter.
	// It returns the updated value of the counter.
	http.HandleFunc("/api/add", func(w http.ResponseWriter, r *http.Request) {
		// Unmarshal the request from the client.
		var val struct{ N int64 }
		if err := json.UnmarshalRead(r.Body, &val); err != nil {
			// Inability to unmarshal the input suggests a client-side problem.
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		// Marshal a response from the server.
		val.N = atomic.AddInt64(&n, val.N)
		if err := json.MarshalWrite(w, &val); err != nil {
			// Inability to marshal the output suggests a server-side problem.
			// This error is not always observable by the client since
			// json.MarshalWrite may have already written to the output.
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})
}

// Some Go types have a custom JSON representation where the implementation
// is delegated to some external package. Consequently, the "json" package
// will not know how to use that external implementation.
// For example, the [google.golang.org/protobuf/encoding/protojson] package
// implements JSON for all [google.golang.org/protobuf/proto.Message] types.
// [WithMarshalers] and [WithUnmarshalers] can be used
// to configure "json" and "protojson" to cooperate together.
func Example_protoJSON() {
	// Let protoMessage be "google.golang.org/protobuf/proto".Message.
	type protoMessage interface{ ProtoReflect() }
	// Let foopbMyMessage be a concrete implementation of proto.Message.
	type foopbMyMessage struct{ protoMessage }
	// Let protojson be an import of "google.golang.org/protobuf/encoding/protojson".
	var protojson struct {
		Marshal   func(protoMessage) ([]byte, error)
		Unmarshal func([]byte, protoMessage) error
	}

	// This value mixes both non-proto.Message types and proto.Message types.
	// It should use the "json" package to handle non-proto.Message types and
	// should use the "protojson" package to handle proto.Message types.
	var value struct {
		// GoStruct does not implement proto.Message and
		// should use the default behavior of the "json" package.
		GoStruct struct {
			Name string
			Age  int
		}

		// ProtoMessage implements proto.Message and
		// should be handled using protojson.Marshal.
		ProtoMessage *foopbMyMessage
	}

	// Marshal using protojson.Marshal for proto.Message types.
	b, err := json.Marshal(&value,
		// Use protojson.Marshal as a type-specific marshaler.
		json.WithMarshalers(json.MarshalFunc(protojson.Marshal)))
	if err != nil {
		log.Fatal(err)
	}

	// Unmarshal using protojson.Unmarshal for proto.Message types.
	err = json.Unmarshal(b, &value,
		// Use protojson.Unmarshal as a type-specific unmarshaler.
		json.WithUnmarshalers(json.UnmarshalFunc(protojson.Unmarshal)))
	if err != nil {
		log.Fatal(err)
	}
}

// Many error types are not serializable since they tend to be Go structs
// without any exported fields (e.g., errors constructed with [errors.New]).
// Some applications, may desire to marshal an error as a JSON string
// even if these errors cannot be unmarshaled.
func ExampleWithMarshalers_errors() {
	// Response to serialize with some Go errors encountered.
	response := []struct {
		Result string `json:",omitzero"`
		Error  error  `json:",omitzero"`
	}{
		{Result: "Oranges are a good source of Vitamin C."},
		{Error: &strconv.NumError{Func: "ParseUint", Num: "-1234", Err: strconv.ErrSyntax}},
		{Error: &os.PathError{Op: "ReadFile", Path: "/path/to/secret/file", Err: os.ErrPermission}},
	}

	b, err := json.Marshal(&response,
		// Intercept every attempt to marshal an error type.
		json.WithMarshalers(json.JoinMarshalers(
			// Suppose we consider strconv.NumError to be a safe to serialize:
			// this type-specific marshal function intercepts this type
			// and encodes the error message as a JSON string.
			json.MarshalToFunc(func(enc *jsontext.Encoder, err *strconv.NumError) error {
				return enc.WriteToken(jsontext.String(err.Error()))
			}),
			// Error messages may contain sensitive information that may not
			// be appropriate to serialize. For all errors not handled above,
			// report some generic error message.
			json.MarshalFunc(func(error) ([]byte, error) {
				return []byte(`"internal server error"`), nil
			}),
		)),
		jsontext.Multiline(true)) // expand for readability
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))

	// Output:
	// [
	// 	{
	// 		"Result": "Oranges are a good source of Vitamin C."
	// 	},
	// 	{
	// 		"Error": "strconv.ParseUint: parsing \"-1234\": invalid syntax"
	// 	},
	// 	{
	// 		"Error": "internal server error"
	// 	}
	// ]
}

// In some applications, the exact precision of JSON numbers needs to be
// preserved when unmarshaling. This can be accomplished using a type-specific
// unmarshal function that intercepts all any types and pre-populates the
// interface value with a [jsontext.Value], which can represent a JSON number exactly.
func ExampleWithUnmarshalers_rawNumber() {
	// Input with JSON numbers beyond the representation of a float64.
	const input = `[false, 1e-1000, 3.141592653589793238462643383279, 1e+1000, true]`

	var value any
	err := json.Unmarshal([]byte(input), &value,
		// Intercept every attempt to unmarshal into the any type.
		json.WithUnmarshalers(
			json.UnmarshalFromFunc(func(dec *jsontext.Decoder, val *any) error {
				// If the next value to be decoded is a JSON number,
				// then provide a concrete Go type to unmarshal into.
				if dec.PeekKind() == '0' {
					*val = jsontext.Value(nil)
				}
				// Return ErrUnsupported to fallback on default unmarshal behavior.
				return errors.ErrUnsupported
			}),
		))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(value)

	// Sanity check.
	want := []any{false, jsontext.Value("1e-1000"), jsontext.Value("3.141592653589793238462643383279"), jsontext.Value("1e+1000"), true}
	if !reflect.DeepEqual(value, want) {
		log.Fatalf("value mismatch:\ngot  %v\nwant %v", value, want)
	}

	// Output:
	// [false 1e-1000 3.141592653589793238462643383279 1e+1000 true]
}

// When using JSON for parsing configuration files,
// the parsing logic often needs to report an error with a line and column
// indicating where in the input an error occurred.
func ExampleWithUnmarshalers_recordOffsets() {
	// Hypothetical configuration file.
	const input = `[
		{"Source": "192.168.0.100:1234", "Destination": "192.168.0.1:80"},
		{"Source": "192.168.0.251:4004"},
		{"Source": "192.168.0.165:8080", "Destination": "0.0.0.0:80"}
	]`
	type Tunnel struct {
		Source      netip.AddrPort
		Destination netip.AddrPort

		// ByteOffset is populated during unmarshal with the byte offset
		// within the JSON input of the JSON object for this Go struct.
		ByteOffset int64 `json:"-"` // metadata to be ignored for JSON serialization
	}

	var tunnels []Tunnel
	err := json.Unmarshal([]byte(input), &tunnels,
		// Intercept every attempt to unmarshal into the Tunnel type.
		json.WithUnmarshalers(
			json.UnmarshalFromFunc(func(dec *jsontext.Decoder, tunnel *Tunnel) error {
				// Decoder.InputOffset reports the offset after the last token,
				// but we want to record the offset before the next token.
				//
				// Call Decoder.PeekKind to buffer enough to reach the next token.
				// Add the number of leading whitespace, commas, and colons
				// to locate the start of the next token.
				dec.PeekKind()
				unread := dec.UnreadBuffer()
				n := len(unread) - len(bytes.TrimLeft(unread, " \n\r\t,:"))
				tunnel.ByteOffset = dec.InputOffset() + int64(n)

				// Return ErrUnsupported to fallback on default unmarshal behavior.
				return errors.ErrUnsupported
			}),
		))
	if err != nil {
		log.Fatal(err)
	}

	// lineColumn converts a byte offset into a one-indexed line and column.
	// The offset must be within the bounds of the input.
	lineColumn := func(input string, offset int) (line, column int) {
		line = 1 + strings.Count(input[:offset], "\n")
		column = 1 + offset - (strings.LastIndex(input[:offset], "\n") + len("\n"))
		return line, column
	}

	// Verify that the configuration file is valid.
	for _, tunnel := range tunnels {
		if !tunnel.Source.IsValid() || !tunnel.Destination.IsValid() {
			line, column := lineColumn(input, int(tunnel.ByteOffset))
			fmt.Printf("%d:%d: source and destination must both be specified", line, column)
		}
	}

	// Output:
	// 3:3: source and destination must both be specified
}

// UnmarshalDecode can be used to unmarshal a stream of whitespace-delimited
// JSON values.
func ExampleUnmarshalDecode_stream() {
	const jsonStream = `
	{"Name": "Platypus", "Order": "Monotremata"}
	{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	{"Name": "Gopher",   "Order": "Rodentia"}
`
	type Animal struct {
		Name  string
		Order string
	}
	dec := jsontext.NewDecoder(strings.NewReader(jsonStream))
	for {
		var a Animal
		if err := json.UnmarshalDecode(dec, &a); err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s: %s\n", a.Name, a.Order)
	}
	// Output:
	// Platypus: Monotremata
	// Quoll: Dasyuromorphia
	// Gopher: Rodentia
}

// Use [jsontext.Multiline] to create multiline, idented output for more
// readable output for human consumption.
//
// See [jsontext.Multiline] for additional options that customize the multiline
// output.
func ExampleMarshal_multiline() {
	type Pet struct {
		Name    string
		Species string
		Breed   string
	}

	p := Pet{
		Name:    "Oliver",
		Species: "Dog",
		Breed:   "Goldendoodle",
	}

	b, err := json.Marshal(p, jsontext.Multiline(true))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(b))
	// Output:
	// {
	// 	"Name": "Oliver",
	// 	"Species": "Dog",
	// 	"Breed": "Goldendoodle"
	// }
}
