package assertions

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"reflect"
	"strings"

	"github.com/smartystreets/assertions/internal/go-render/render"
	"github.com/smartystreets/assertions/internal/oglematchers"
)

// ShouldEqual receives exactly two parameters and does an equality check
// using the following semantics:
// 1. If the expected and actual values implement an Equal method in the form
// `func (this T) Equal(that T) bool` then call the method. If true, they are equal.
// 2. The expected and actual values are judged equal or not by oglematchers.Equals.
func ShouldEqual(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	}
	return shouldEqual(actual, expected[0])
}
func shouldEqual(actual, expected interface{}) (message string) {
	defer func() {
		if r := recover(); r != nil {
			message = serializer.serialize(expected, actual, composeEqualityMismatchMessage(expected, actual))
		}
	}()

	if spec := newEqualityMethodSpecification(expected, actual); spec.IsSatisfied() && spec.AreEqual() {
		return success
	} else if matchError := oglematchers.Equals(expected).Matches(actual); matchError == nil {
		return success
	}

	return serializer.serialize(expected, actual, composeEqualityMismatchMessage(expected, actual))
}
func composeEqualityMismatchMessage(expected, actual interface{}) string {
	var (
		renderedExpected = fmt.Sprintf("%v", expected)
		renderedActual   = fmt.Sprintf("%v", actual)
	)

	if renderedExpected != renderedActual {
		return fmt.Sprintf(shouldHaveBeenEqual+composePrettyDiff(renderedExpected, renderedActual), expected, actual)
	} else if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
		return fmt.Sprintf(shouldHaveBeenEqualTypeMismatch, expected, expected, actual, actual)
	} else {
		return fmt.Sprintf(shouldHaveBeenEqualNoResemblance, renderedExpected)
	}
}

// ShouldNotEqual receives exactly two parameters and does an inequality check.
// See ShouldEqual for details on how equality is determined.
func ShouldNotEqual(actual interface{}, expected ...interface{}) string {
	if fail := need(1, expected); fail != success {
		return fail
	} else if ShouldEqual(actual, expected[0]) == success {
		return fmt.Sprintf(shouldNotHaveBeenEqual, actual, expected[0])
	}
	return success
}

// ShouldAlmostEqual makes sure that two parameters are close enough to being equal.
// The acceptable delta may be specified with a third argument,
// or a very small default delta will be used.
func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string {
	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)

	if err != "" {
		return err
	}

	if math.Abs(actualFloat-expectedFloat) <= deltaFloat {
		return success
	} else {
		return fmt.Sprintf(shouldHaveBeenAlmostEqual, actualFloat, expectedFloat)
	}
}

// ShouldNotAlmostEqual is the inverse of ShouldAlmostEqual
func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string {
	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)

	if err != "" {
		return err
	}

	if math.Abs(actualFloat-expectedFloat) > deltaFloat {
		return success
	} else {
		return fmt.Sprintf(shouldHaveNotBeenAlmostEqual, actualFloat, expectedFloat)
	}
}

func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64, float64, float64, string) {
	deltaFloat := 0.0000000001

	if len(expected) == 0 {
		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided neither)"
	} else if len(expected) == 2 {
		delta, err := getFloat(expected[1])

		if err != nil {
			return 0.0, 0.0, 0.0, "The delta value " + err.Error()
		}

		deltaFloat = delta
	} else if len(expected) > 2 {
		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided more values)"
	}

	actualFloat, err := getFloat(actual)
	if err != nil {
		return 0.0, 0.0, 0.0, "The actual value " + err.Error()
	}

	expectedFloat, err := getFloat(expected[0])
	if err != nil {
		return 0.0, 0.0, 0.0, "The comparison value " + err.Error()
	}

	return actualFloat, expectedFloat, deltaFloat, ""
}

// returns the float value of any real number, or error if it is not a numerical type
func getFloat(num interface{}) (float64, error) {
	numValue := reflect.ValueOf(num)
	numKind := numValue.Kind()

	if numKind == reflect.Int ||
		numKind == reflect.Int8 ||
		numKind == reflect.Int16 ||
		numKind == reflect.Int32 ||
		numKind == reflect.Int64 {
		return float64(numValue.Int()), nil
	} else if numKind == reflect.Uint ||
		numKind == reflect.Uint8 ||
		numKind == reflect.Uint16 ||
		numKind == reflect.Uint32 ||
		numKind == reflect.Uint64 {
		return float64(numValue.Uint()), nil
	} else if numKind == reflect.Float32 ||
		numKind == reflect.Float64 {
		return numValue.Float(), nil
	} else {
		return 0.0, errors.New("must be a numerical type, but was: " + numKind.String())
	}
}

// ShouldEqualJSON receives exactly two parameters and does an equality check by marshalling to JSON
func ShouldEqualJSON(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	}

	expectedString, expectedErr := remarshal(expected[0].(string))
	if expectedErr != nil {
		return "Expected value not valid JSON: " + expectedErr.Error()
	}

	actualString, actualErr := remarshal(actual.(string))
	if actualErr != nil {
		return "Actual value not valid JSON: " + actualErr.Error()
	}

	return ShouldEqual(actualString, expectedString)
}
func remarshal(value string) (string, error) {
	var structured interface{}
	err := json.Unmarshal([]byte(value), &structured)
	if err != nil {
		return "", err
	}
	canonical, _ := json.Marshal(structured)
	return string(canonical), nil
}

// ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual)
func ShouldResemble(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	}

	if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil {
		renderedExpected, renderedActual := render.Render(expected[0]), render.Render(actual)
		message := fmt.Sprintf(shouldHaveResembled, renderedExpected, renderedActual) +
			composePrettyDiff(renderedExpected, renderedActual)
		return serializer.serializeDetailed(expected[0], actual, message)
	}

	return success
}

// ShouldNotResemble receives exactly two parameters and does an inverse deep equal check (see reflect.DeepEqual)
func ShouldNotResemble(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	} else if ShouldResemble(actual, expected[0]) == success {
		return fmt.Sprintf(shouldNotHaveResembled, render.Render(actual), render.Render(expected[0]))
	}
	return success
}

// ShouldPointTo receives exactly two parameters and checks to see that they point to the same address.
func ShouldPointTo(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	}
	return shouldPointTo(actual, expected[0])

}
func shouldPointTo(actual, expected interface{}) string {
	actualValue := reflect.ValueOf(actual)
	expectedValue := reflect.ValueOf(expected)

	if ShouldNotBeNil(actual) != success {
		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "nil")
	} else if ShouldNotBeNil(expected) != success {
		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "nil")
	} else if actualValue.Kind() != reflect.Ptr {
		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "not")
	} else if expectedValue.Kind() != reflect.Ptr {
		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "not")
	} else if ShouldEqual(actualValue.Pointer(), expectedValue.Pointer()) != success {
		actualAddress := reflect.ValueOf(actual).Pointer()
		expectedAddress := reflect.ValueOf(expected).Pointer()
		return serializer.serialize(expectedAddress, actualAddress, fmt.Sprintf(shouldHavePointedTo,
			actual, actualAddress,
			expected, expectedAddress))
	}
	return success
}

// ShouldNotPointTo receives exactly two parameters and checks to see that they point to different addresess.
func ShouldNotPointTo(actual interface{}, expected ...interface{}) string {
	if message := need(1, expected); message != success {
		return message
	}
	compare := ShouldPointTo(actual, expected[0])
	if strings.HasPrefix(compare, shouldBePointers) {
		return compare
	} else if compare == success {
		return fmt.Sprintf(shouldNotHavePointedTo, actual, expected[0], reflect.ValueOf(actual).Pointer())
	}
	return success
}

// ShouldBeNil receives a single parameter and ensures that it is nil.
func ShouldBeNil(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	} else if actual == nil {
		return success
	} else if interfaceHasNilValue(actual) {
		return success
	}
	return fmt.Sprintf(shouldHaveBeenNil, actual)
}
func interfaceHasNilValue(actual interface{}) bool {
	value := reflect.ValueOf(actual)
	kind := value.Kind()
	nilable := kind == reflect.Slice ||
		kind == reflect.Chan ||
		kind == reflect.Func ||
		kind == reflect.Ptr ||
		kind == reflect.Map

	// Careful: reflect.Value.IsNil() will panic unless it's an interface, chan, map, func, slice, or ptr
	// Reference: http://golang.org/pkg/reflect/#Value.IsNil
	return nilable && value.IsNil()
}

// ShouldNotBeNil receives a single parameter and ensures that it is not nil.
func ShouldNotBeNil(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	} else if ShouldBeNil(actual) == success {
		return fmt.Sprintf(shouldNotHaveBeenNil, actual)
	}
	return success
}

// ShouldBeTrue receives a single parameter and ensures that it is true.
func ShouldBeTrue(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	} else if actual != true {
		return fmt.Sprintf(shouldHaveBeenTrue, actual)
	}
	return success
}

// ShouldBeFalse receives a single parameter and ensures that it is false.
func ShouldBeFalse(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	} else if actual != false {
		return fmt.Sprintf(shouldHaveBeenFalse, actual)
	}
	return success
}

// ShouldBeZeroValue receives a single parameter and ensures that it is
// the Go equivalent of the default value, or "zero" value.
func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	}
	zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface()
	if !reflect.DeepEqual(zeroVal, actual) {
		return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldHaveBeenZeroValue, actual))
	}
	return success
}

// ShouldBeZeroValue receives a single parameter and ensures that it is NOT
// the Go equivalent of the default value, or "zero" value.
func ShouldNotBeZeroValue(actual interface{}, expected ...interface{}) string {
	if fail := need(0, expected); fail != success {
		return fail
	}
	zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface()
	if reflect.DeepEqual(zeroVal, actual) {
		return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldNotHaveBeenZeroValue, actual))
	}
	return success
}
