// Copyright 2020 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.

package order

import (
	"math/rand"
	"sort"
	"testing"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/protobuf/reflect/protoreflect"
)

type fieldDesc struct {
	index      int
	name       protoreflect.FullName
	number     protoreflect.FieldNumber
	extension  bool
	oneofIndex int // non-zero means within oneof; negative means synthetic
	protoreflect.FieldDescriptor
}

func (d fieldDesc) Index() int                       { return d.index }
func (d fieldDesc) Name() protoreflect.Name          { return d.name.Name() }
func (d fieldDesc) FullName() protoreflect.FullName  { return d.name }
func (d fieldDesc) Number() protoreflect.FieldNumber { return d.number }
func (d fieldDesc) IsExtension() bool                { return d.extension }
func (d fieldDesc) ContainingOneof() protoreflect.OneofDescriptor {
	switch {
	case d.oneofIndex < 0:
		return oneofDesc{index: -d.oneofIndex, synthetic: true}
	case d.oneofIndex > 0:
		return oneofDesc{index: +d.oneofIndex, synthetic: false}
	default:
		return nil
	}
}

type oneofDesc struct {
	index     int
	synthetic bool
	protoreflect.OneofDescriptor
}

func (d oneofDesc) Index() int        { return d.index }
func (d oneofDesc) IsSynthetic() bool { return d.synthetic }

func TestFieldOrder(t *testing.T) {
	tests := []struct {
		label  string
		order  FieldOrder
		fields []fieldDesc
	}{{
		label: "LegacyFieldOrder",
		order: LegacyFieldOrder,
		fields: []fieldDesc{
			// Extension fields sorted first by field number.
			{number: 2, extension: true},
			{number: 4, extension: true},
			{number: 100, extension: true},
			{number: 120, extension: true},

			// Non-extension fields that are not within a oneof
			// sorted next by field number.
			{number: 1},
			{number: 5, oneofIndex: -10}, // synthetic oneof
			{number: 10},
			{number: 11, oneofIndex: -9}, // synthetic oneof
			{number: 12},

			// Non-synthetic oneofs sorted last by index.
			{number: 13, oneofIndex: 4},
			{number: 3, oneofIndex: 5},
			{number: 9, oneofIndex: 5},
			{number: 7, oneofIndex: 8},
		},
	}, {
		label: "NumberFieldOrder",
		order: NumberFieldOrder,
		fields: []fieldDesc{
			{number: 1, index: 5, name: "c"},
			{number: 2, index: 2, name: "b"},
			{number: 3, index: 3, name: "d"},
			{number: 5, index: 1, name: "a"},
			{number: 7, index: 7, name: "e"},
		},
	}, {
		label: "IndexNameFieldOrder",
		order: IndexNameFieldOrder,
		fields: []fieldDesc{
			// Non-extension fields sorted first by index.
			{index: 0, number: 5, name: "c"},
			{index: 2, number: 2, name: "a"},
			{index: 4, number: 4, name: "b"},
			{index: 7, number: 6, name: "d"},

			// Extension fields sorted last by full name.
			{index: 3, number: 1, name: "d.a", extension: true},
			{index: 5, number: 3, name: "e", extension: true},
			{index: 1, number: 7, name: "g", extension: true},
		},
	}}

	for _, tt := range tests {
		t.Run(tt.label, func(t *testing.T) {
			want := tt.fields
			got := append([]fieldDesc(nil), want...)
			for i, j := range rand.Perm(len(got)) {
				got[i], got[j] = got[j], got[i]
			}
			sort.Slice(got, func(i, j int) bool {
				return tt.order(got[i], got[j])
			})
			if diff := cmp.Diff(want, got,
				cmp.Comparer(func(x, y fieldDesc) bool { return x == y }),
			); diff != "" {
				t.Errorf("order mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestKeyOrder(t *testing.T) {
	tests := []struct {
		label string
		order KeyOrder
		keys  []any
	}{{
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{false, true},
	}, {
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{int32(-100), int32(-99), int32(-10), int32(-9), int32(-1), int32(0), int32(+1), int32(+9), int32(+10), int32(+99), int32(+100)},
	}, {
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{int64(-100), int64(-99), int64(-10), int64(-9), int64(-1), int64(0), int64(+1), int64(+9), int64(+10), int64(+99), int64(+100)},
	}, {
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{uint32(0), uint32(1), uint32(9), uint32(10), uint32(99), uint32(100)},
	}, {
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{uint64(0), uint64(1), uint64(9), uint64(10), uint64(99), uint64(100)},
	}, {
		label: "GenericKeyOrder",
		order: GenericKeyOrder,
		keys:  []any{"", "a", "aa", "ab", "ba", "bb", "\u0080", "\u0080\u0081", "\u0082\u0080"},
	}}

	for _, tt := range tests {
		t.Run(tt.label, func(t *testing.T) {
			var got, want []protoreflect.MapKey
			for _, v := range tt.keys {
				want = append(want, protoreflect.ValueOf(v).MapKey())
			}
			got = append(got, want...)
			for i, j := range rand.Perm(len(got)) {
				got[i], got[j] = got[j], got[i]
			}
			sort.Slice(got, func(i, j int) bool {
				return tt.order(got[i], got[j])
			})
			if diff := cmp.Diff(want, got, cmp.Transformer("", protoreflect.MapKey.Interface)); diff != "" {
				t.Errorf("order mismatch (-want +got):\n%s", diff)
			}
		})
	}
}
