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

import (
	"reflect"
	"testing"

	"encoding/json/internal/jsonflags"
	. "encoding/json/internal/jsonopts"
	"encoding/json/jsontext"
	"encoding/json/v2"
)

func makeFlags(f ...jsonflags.Bools) (fs jsonflags.Flags) {
	for _, f := range f {
		fs.Set(f)
	}
	return fs
}

func TestJoin(t *testing.T) {
	tests := []struct {
		in   Options
		want *Struct
	}{{
		in:   jsonflags.AllowInvalidUTF8 | 1,
		want: &Struct{Flags: makeFlags(jsonflags.AllowInvalidUTF8 | 1)},
	}, {
		in: jsonflags.Multiline | 0,
		want: &Struct{
			Flags: makeFlags(jsonflags.AllowInvalidUTF8|1, jsonflags.Multiline|0)},
	}, {
		in: Indent("\t"), // implicitly sets Multiline=true
		want: &Struct{
			Flags:       makeFlags(jsonflags.AllowInvalidUTF8 | jsonflags.Multiline | jsonflags.Indent | 1),
			CoderValues: CoderValues{Indent: "\t"},
		},
	}, {
		in: &Struct{
			Flags: makeFlags(jsonflags.Multiline|jsonflags.EscapeForJS|0, jsonflags.AllowInvalidUTF8|1),
		},
		want: &Struct{
			Flags:       makeFlags(jsonflags.AllowInvalidUTF8|jsonflags.Indent|1, jsonflags.Multiline|jsonflags.EscapeForJS|0),
			CoderValues: CoderValues{Indent: "\t"},
		},
	}, {
		in: &DefaultOptionsV1,
		want: func() *Struct {
			v1 := DefaultOptionsV1
			v1.Flags.Set(jsonflags.Indent | 1)
			v1.Flags.Set(jsonflags.Multiline | 0)
			v1.Indent = "\t"
			return &v1
		}(), // v1 fully replaces before (except for whitespace related flags)
	}, {
		in: &DefaultOptionsV2,
		want: func() *Struct {
			v2 := DefaultOptionsV2
			v2.Flags.Set(jsonflags.Indent | 1)
			v2.Flags.Set(jsonflags.Multiline | 0)
			v2.Indent = "\t"
			return &v2
		}(), // v2 fully replaces before (except for whitespace related flags)
	}, {
		in: jsontext.WithIndentPrefix("    "),
		want: func() *Struct {
			v2 := DefaultOptionsV2
			v2.Flags.Set(jsonflags.Indent | 1)
			v2.Flags.Set(jsonflags.IndentPrefix | 1)
			v2.Flags.Set(jsonflags.Multiline | 1)
			v2.Indent = "\t"
			v2.IndentPrefix = "    "
			return &v2
		}(),
	}, {
		in: &Struct{
			Flags: jsonflags.Flags{
				Presence: uint64(jsonflags.Deterministic | jsonflags.Indent | jsonflags.IndentPrefix),
				Values:   uint64(jsonflags.Indent | jsonflags.IndentPrefix),
			},
			CoderValues: CoderValues{Indent: "  ", IndentPrefix: "  "},
		},
		want: func() *Struct {
			v2 := DefaultOptionsV2
			v2.Flags.Set(jsonflags.Indent | 1)
			v2.Flags.Set(jsonflags.IndentPrefix | 1)
			v2.Flags.Set(jsonflags.Multiline | 1)
			v2.Indent = "  "
			v2.IndentPrefix = "  "
			return &v2
		}(),
	}, {
		in: ExperimentalSupportFormatTag(true),
		want: func() *Struct {
			v2 := DefaultOptionsV2
			v2.Flags.Set(jsonflags.Indent | 1)
			v2.Flags.Set(jsonflags.IndentPrefix | 1)
			v2.Flags.Set(jsonflags.Multiline | 1)
			v2.Flags.Set(jsonflags.FormatTagSupported | 1)
			v2.Indent = "  "
			v2.IndentPrefix = "  "
			return &v2
		}(),
	}, {
		in: &Struct{Flags: jsonflags.Flags{Presence: uint64(jsonflags.FormatTagSupported)}},
		want: func() *Struct {
			v2 := DefaultOptionsV2
			v2.Flags.Set(jsonflags.Indent | 1)
			v2.Flags.Set(jsonflags.IndentPrefix | 1)
			v2.Flags.Set(jsonflags.Multiline | 1)
			v2.Flags.Set(jsonflags.FormatTagSupported | 0)
			v2.Indent = "  "
			v2.IndentPrefix = "  "
			return &v2
		}(),
	}}
	got := new(Struct)
	for i, tt := range tests {
		got.Join(tt.in)
		if !reflect.DeepEqual(got, tt.want) {
			t.Fatalf("%d: Join:\n\tgot:  %+v\n\twant: %+v", i, got, tt.want)
		}
	}
}

func TestGet(t *testing.T) {
	opts := &Struct{
		Flags:        makeFlags(jsonflags.Indent|jsonflags.Deterministic|jsonflags.Marshalers|jsonflags.FormatTagSupported|1, jsonflags.Multiline|0),
		CoderValues:  CoderValues{Indent: "\t"},
		ArshalValues: ArshalValues{Marshalers: new(json.Marshalers)},
	}
	if v, ok := json.GetOption(nil, jsontext.AllowDuplicateNames); v || ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
	}
	if v, ok := json.GetOption(jsonflags.AllowInvalidUTF8|0, jsontext.AllowDuplicateNames); v || ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
	}
	if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|0, jsontext.AllowDuplicateNames); v || !ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, true)", v, ok)
	}
	if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|1, jsontext.AllowDuplicateNames); !v || !ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (true, true)", v, ok)
	}
	if v, ok := json.GetOption(Indent(""), jsontext.AllowDuplicateNames); v || ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
	}
	if v, ok := json.GetOption(Indent(" "), jsontext.WithIndent); v != " " || !ok {
		t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want (" ", true)`, v, ok)
	}
	if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|1, jsontext.WithIndent); v != "" || ok {
		t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want ("", false)`, v, ok)
	}
	if v, ok := json.GetOption(opts, jsontext.AllowDuplicateNames); v || ok {
		t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
	}
	if v, ok := json.GetOption(opts, json.Deterministic); !v || !ok {
		t.Errorf("GetOption(..., Deterministic) = (%v, %v), want (true, true)", v, ok)
	}
	if v, ok := json.GetOption(opts, jsontext.Multiline); v || !ok {
		t.Errorf("GetOption(..., Multiline) = (%v, %v), want (false, true)", v, ok)
	}
	if v, ok := json.GetOption(opts, jsontext.AllowInvalidUTF8); v || ok {
		t.Errorf("GetOption(..., AllowInvalidUTF8) = (%v, %v), want (false, false)", v, ok)
	}
	if v, ok := json.GetOption(opts, jsontext.WithIndent); v != "\t" || !ok {
		t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want ("\t", true)`, v, ok)
	}
	if v, ok := json.GetOption(opts, jsontext.WithIndentPrefix); v != "" || ok {
		t.Errorf(`GetOption(..., WithIndentPrefix) = (%q, %v), want ("", false)`, v, ok)
	}
	if v, ok := json.GetOption(opts, json.WithMarshalers); v == nil || !ok {
		t.Errorf(`GetOption(..., WithMarshalers) = (%v, %v), want (non-nil, true)`, v, ok)
	}
	if v, ok := json.GetOption(opts, json.WithUnmarshalers); v != nil || ok {
		t.Errorf(`GetOption(..., WithUnmarshalers) = (%v, %v), want (nil, false)`, v, ok)
	}
	if v, ok := json.GetOption(json.DefaultOptionsV2(), json.WithMarshalers); v != nil || ok {
		t.Errorf(`GetOption(..., WithMarshalers) = (%v, %v), want (nil, false)`, v, ok)
	}
	if v, ok := json.GetOption(opts, ExperimentalSupportFormatTag); !v || !ok {
		t.Errorf(`GetOption(..., ExperimentalSupportFormatTag) = (%v, %v), want (true, true)`, v, ok)
	}
	if v, ok := json.GetOption(json.DefaultOptionsV2(), ExperimentalSupportFormatTag); v || ok {
		t.Errorf(`GetOption(..., ExperimentalSupportFormatTag) = (%v, %v), want (false, false)`, v, ok)
	}
}

var sink struct {
	Bool       bool
	String     string
	Marshalers *json.Marshalers
}

func BenchmarkGetBool(b *testing.B) {
	b.ReportAllocs()
	opts := json.DefaultOptionsV2()
	for range b.N {
		sink.Bool, sink.Bool = json.GetOption(opts, jsontext.AllowDuplicateNames)
	}
}

func BenchmarkGetIndent(b *testing.B) {
	b.ReportAllocs()
	opts := json.DefaultOptionsV2()
	for range b.N {
		sink.String, sink.Bool = json.GetOption(opts, jsontext.WithIndent)
	}
}

func BenchmarkGetMarshalers(b *testing.B) {
	b.ReportAllocs()
	opts := json.JoinOptions(json.DefaultOptionsV2(), json.WithMarshalers(nil))
	for range b.N {
		sink.Marshalers, sink.Bool = json.GetOption(opts, json.WithMarshalers)
	}
}
