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

package compare

import (
	"cmd/compile/internal/base"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/src"
	"cmd/internal/sys"
	"testing"
)

type typefn func() *types.Type

func init() {
	// These are the few constants that need to be initialized in order to use
	// the types package without using the typecheck package by calling
	// typecheck.InitUniverse() (the normal way to initialize the types package).
	types.PtrSize = 8
	types.RegSize = 8
	types.MaxWidth = 1 << 50
	typecheck.InitUniverse()
	base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
}

func TestEqStructCost(t *testing.T) {
	newByteField := func(parent *types.Type, offset int64) *types.Field {
		f := types.NewField(src.XPos{}, parent.Sym(), types.ByteType)
		f.Offset = offset
		return f
	}
	newArrayField := func(parent *types.Type, offset int64, len int64, kind types.Kind) *types.Field {
		f := types.NewField(src.XPos{}, parent.Sym(), types.NewArray(types.Types[kind], len))
		// Call Type.Size here to force the size calculation to be done. If not done here the size returned later is incorrect.
		f.Type.Size()
		f.Offset = offset
		return f
	}
	newField := func(parent *types.Type, offset int64, kind types.Kind) *types.Field {
		f := types.NewField(src.XPos{}, parent.Sym(), types.Types[kind])
		f.Offset = offset
		return f
	}
	tt := []struct {
		name             string
		cost             int64
		nonMergeLoadCost int64
		tfn              typefn
	}{
		{"struct without fields", 0, 0,
			func() *types.Type {
				return types.NewStruct([]*types.Field{})
			}},
		{"struct with 1 byte field", 1, 1,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := []*types.Field{
					newByteField(parent, 0),
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 8 byte fields", 1, 8,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 8)
				for i := range fields {
					fields[i] = newByteField(parent, int64(i))
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 16 byte fields", 2, 16,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 16)
				for i := range fields {
					fields[i] = newByteField(parent, int64(i))
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 32 byte fields", 4, 32,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 32)
				for i := range fields {
					fields[i] = newByteField(parent, int64(i))
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 2 int32 fields", 1, 2,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 2)
				for i := range fields {
					fields[i] = newField(parent, int64(i*4), types.TINT32)
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 2 int32 fields and 1 int64", 2, 3,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 3)
				fields[0] = newField(parent, int64(0), types.TINT32)
				fields[1] = newField(parent, int64(4), types.TINT32)
				fields[2] = newField(parent, int64(8), types.TINT64)
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 1 int field and 1 string", 3, 3,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 2)
				fields[0] = newField(parent, int64(0), types.TINT64)
				fields[1] = newField(parent, int64(8), types.TSTRING)
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 2 strings", 4, 4,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := make([]*types.Field, 2)
				fields[0] = newField(parent, int64(0), types.TSTRING)
				fields[1] = newField(parent, int64(8), types.TSTRING)
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with 1 large byte array field", 26, 101,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := []*types.Field{
					newArrayField(parent, 0, 101, types.TUINT16),
				}
				parent.SetFields(fields)
				return parent
			},
		},
		{"struct with string array field", 4, 4,
			func() *types.Type {
				parent := types.NewStruct([]*types.Field{})
				fields := []*types.Field{
					newArrayField(parent, 0, 2, types.TSTRING),
				}
				parent.SetFields(fields)
				return parent
			},
		},
	}

	for _, tc := range tt {
		t.Run(tc.name, func(t *testing.T) {
			want := tc.cost
			base.Ctxt.Arch.CanMergeLoads = true
			actual := EqStructCost(tc.tfn())
			if actual != want {
				t.Errorf("CanMergeLoads=true EqStructCost(%v) = %d, want %d", tc.tfn, actual, want)
			}

			base.Ctxt.Arch.CanMergeLoads = false
			want = tc.nonMergeLoadCost
			actual = EqStructCost(tc.tfn())
			if actual != want {
				t.Errorf("CanMergeLoads=false EqStructCost(%v) = %d, want %d", tc.tfn, actual, want)
			}
		})
	}
}
