// 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"
	"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)
	}

	// Print the serialized JSON object.
	(*jsontext.Value)(&b).Indent() // indent for readability
	fmt.Println(string(b))

	// 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)
	}
	(*jsontext.Value)(&b).Indent() // indent for readability
	fmt.Println(string(b))

	// 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)
	}
	(*jsontext.Value)(&b).Indent()      // indent for readability
	fmt.Println("OmitZero:", string(b)) // 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)
	}
	(*jsontext.Value)(&b).Indent()       // indent for readability
	fmt.Println("OmitEmpty:", string(b)) // 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)
	}
	(*jsontext.Value)(&b).Indent() // indent for readability
	fmt.Println(string(b))

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