// Copyright (c) 2019 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 field

import (
	"testing"
	"testing/quick"
)

func checkAliasingOneArg(f func(v, x *Element) *Element) func(v, x Element) bool {
	return func(v, x Element) bool {
		x1, v1 := x, x

		// Calculate a reference f(x) without aliasing.
		if out := f(&v, &x); out != &v && isInBounds(out) {
			return false
		}

		// Test aliasing the argument and the receiver.
		if out := f(&v1, &v1); out != &v1 || v1 != v {
			return false
		}

		// Ensure the arguments was not modified.
		return x == x1
	}
}

func checkAliasingTwoArgs(f func(v, x, y *Element) *Element) func(v, x, y Element) bool {
	return func(v, x, y Element) bool {
		x1, y1, v1 := x, y, Element{}

		// Calculate a reference f(x, y) without aliasing.
		if out := f(&v, &x, &y); out != &v && isInBounds(out) {
			return false
		}

		// Test aliasing the first argument and the receiver.
		v1 = x
		if out := f(&v1, &v1, &y); out != &v1 || v1 != v {
			return false
		}
		// Test aliasing the second argument and the receiver.
		v1 = y
		if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
			return false
		}

		// Calculate a reference f(x, x) without aliasing.
		if out := f(&v, &x, &x); out != &v {
			return false
		}

		// Test aliasing the first argument and the receiver.
		v1 = x
		if out := f(&v1, &v1, &x); out != &v1 || v1 != v {
			return false
		}
		// Test aliasing the second argument and the receiver.
		v1 = x
		if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
			return false
		}
		// Test aliasing both arguments and the receiver.
		v1 = x
		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v {
			return false
		}

		// Ensure the arguments were not modified.
		return x == x1 && y == y1
	}
}

// TestAliasing checks that receivers and arguments can alias each other without
// leading to incorrect results. That is, it ensures that it's safe to write
//
//	v.Invert(v)
//
// or
//
//	v.Add(v, v)
//
// without any of the inputs getting clobbered by the output being written.
func TestAliasing(t *testing.T) {
	type target struct {
		name     string
		oneArgF  func(v, x *Element) *Element
		twoArgsF func(v, x, y *Element) *Element
	}
	for _, tt := range []target{
		{name: "Absolute", oneArgF: (*Element).Absolute},
		{name: "Invert", oneArgF: (*Element).Invert},
		{name: "Negate", oneArgF: (*Element).Negate},
		{name: "Set", oneArgF: (*Element).Set},
		{name: "Square", oneArgF: (*Element).Square},
		{name: "Multiply", twoArgsF: (*Element).Multiply},
		{name: "Add", twoArgsF: (*Element).Add},
		{name: "Subtract", twoArgsF: (*Element).Subtract},
		{
			name: "Select0",
			twoArgsF: func(v, x, y *Element) *Element {
				return (*Element).Select(v, x, y, 0)
			},
		},
		{
			name: "Select1",
			twoArgsF: func(v, x, y *Element) *Element {
				return (*Element).Select(v, x, y, 1)
			},
		},
	} {
		var err error
		switch {
		case tt.oneArgF != nil:
			err = quick.Check(checkAliasingOneArg(tt.oneArgF), &quick.Config{MaxCountScale: 1 << 8})
		case tt.twoArgsF != nil:
			err = quick.Check(checkAliasingTwoArgs(tt.twoArgsF), &quick.Config{MaxCountScale: 1 << 8})
		}
		if err != nil {
			t.Errorf("%v: %v", tt.name, err)
		}
	}
}
