// 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 inlined within a parent object similar to
// how Go structs can be embedded within a parent struct.
// The inlining rules are similar to those of Go embedding,
// but operates upon the JSON namespace.
func Example_inlinedFields() {
	// 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.Inlined.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 inlined.
		Base
		// Type takes precedence over Base.Type.
		Type int
		// Inlined is a named Go field, but is explicitly JSON inlined.
		Inlined struct {
			// User is promoted into the JSON object for Container.
			User string
			// Time cancels out with Base.Time.
			Time string
		} `json:",inline"`
		// ID does not conflict with Base.ID since the JSON name is different.
		ID string `json:"uuid"`
		// Other is not JSON inlined 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
}
