// Copyright 2017, 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.md file.

// Package cmpopts provides common options for the cmp package.
package cmpopts

import (
	"math"
	"reflect"

	"github.com/google/go-cmp/cmp"
)

func equateAlways(_, _ interface{}) bool { return true }

// EquateEmpty returns a Comparer option that determines all maps and slices
// with a length of zero to be equal, regardless of whether they are nil.
//
// EquateEmpty can be used in conjuction with SortSlices and SortMaps.
func EquateEmpty() cmp.Option {
	return cmp.FilterValues(isEmpty, cmp.Comparer(equateAlways))
}

func isEmpty(x, y interface{}) bool {
	vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
	return (x != nil && y != nil && vx.Type() == vy.Type()) &&
		(vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) &&
		(vx.Len() == 0 && vy.Len() == 0)
}

// EquateApprox returns a Comparer option that determines float32 or float64
// values to be equal if they are within a relative fraction or absolute margin.
// This option is not used when either x or y is NaN or infinite.
//
// The fraction determines that the difference of two values must be within the
// smaller fraction of the two values, while the margin determines that the two
// values must be within some absolute margin.
// To express only a fraction or only a margin, use 0 for the other parameter.
// The fraction and margin must be non-negative.
//
// The mathematical expression used is equivalent to:
//	|x-y| ≤ max(fraction*min(|x|, |y|), margin)
//
// EquateApprox can be used in conjuction with EquateNaNs.
func EquateApprox(fraction, margin float64) cmp.Option {
	if margin < 0 || fraction < 0 || math.IsNaN(margin) || math.IsNaN(fraction) {
		panic("margin or fraction must be a non-negative number")
	}
	a := approximator{fraction, margin}
	return cmp.Options{
		cmp.FilterValues(areRealF64s, cmp.Comparer(a.compareF64)),
		cmp.FilterValues(areRealF32s, cmp.Comparer(a.compareF32)),
	}
}

type approximator struct{ frac, marg float64 }

func areRealF64s(x, y float64) bool {
	return !math.IsNaN(x) && !math.IsNaN(y) && !math.IsInf(x, 0) && !math.IsInf(y, 0)
}
func areRealF32s(x, y float32) bool {
	return areRealF64s(float64(x), float64(y))
}
func (a approximator) compareF64(x, y float64) bool {
	relMarg := a.frac * math.Min(math.Abs(x), math.Abs(y))
	return math.Abs(x-y) <= math.Max(a.marg, relMarg)
}
func (a approximator) compareF32(x, y float32) bool {
	return a.compareF64(float64(x), float64(y))
}

// EquateNaNs returns a Comparer option that determines float32 and float64
// NaN values to be equal.
//
// EquateNaNs can be used in conjuction with EquateApprox.
func EquateNaNs() cmp.Option {
	return cmp.Options{
		cmp.FilterValues(areNaNsF64s, cmp.Comparer(equateAlways)),
		cmp.FilterValues(areNaNsF32s, cmp.Comparer(equateAlways)),
	}
}

func areNaNsF64s(x, y float64) bool {
	return math.IsNaN(x) && math.IsNaN(y)
}
func areNaNsF32s(x, y float32) bool {
	return areNaNsF64s(float64(x), float64(y))
}
