// RUN: %empty-directory(%t)
// RUN: %S/../../utils/gyb %s -o %t/FixedPointConversion.swift
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Debug -Onone
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-build-swift %t/FixedPointConversion.swift -o %t/a.out_Release -O
//
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Debug
// RUN: %S/../../utils/line-directive %t/FixedPointConversion.swift -- %target-run %t/a.out_Release
// REQUIRES: executable_test

// FIXME(integers): add tests that perform the same checks in generic code

%{
import gyb
}%

import StdlibUnittest

var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps")
var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures")

var FloatingPointConversionTruncations = TestSuite("FloatingPointToFixedPointConversionTruncations")
var FloatingPointConversionTraps = TestSuite("FloatingPointConversionTraps")
var FloatingPointConversionFailures = TestSuite("FloatingPointToFixedPointConversionFailures")

func getInfiniteOrNaNMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "either infinite or NaN"
  }
  return ""
}

func getTooSmallMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "would be less than"
  }
  return ""
}

func getTooLargeMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "would be greater than"
  }
  return ""
}

%{

int_to_int_conversion_template = gyb.parse_template("int_to_int_conversion",
"""
%{
from SwiftIntTypes import all_integer_types, int_max, int_min
from SwiftFloatingPointTypes import all_floating_point_types

}%
% for self_ty in all_integer_types(word_bits):
%   selfBits = self_ty.bits
%   selfSigned = self_ty.is_signed
%   selfMin = self_ty.min
%   selfMax = self_ty.max
%   Self = self_ty.stdlib_name

%   for other_ty in all_integer_types(word_bits):
%     otherBits = other_ty.bits
%     otherSigned = other_ty.is_signed
%     otherMin = other_ty.min
%     otherMax = other_ty.max
%     Other = other_ty.stdlib_name

%     for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]:

%       if testValue < otherMin or testValue > otherMax:
%          # Can't construct `other` value, do nothing and continue.

%       elif testValue >= selfMin and testValue <= selfMax:

/// Always-safe conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that nothing interesting happens and we end up with the same result after converting.
  let input = get${Other}(${testValue})
  expectEqual(${testValue}, ${Self}(input))
}

/// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
  // Test that nothing interesting happens and we end up with a non-nil, identical result.
  let input = get${Other}(${testValue})
  var result = ${Self}(exactly: input)
  expectEqual(${testValue}, result)
}

%       else:

/// Always-failing conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that we check if we fail and crash when an integer would be truncated in conversion.
  let input = get${Other}(${testValue})
  expectCrashLater()
  var result = ${Self}(input)
  _blackHole(result)
}

/// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that we check if we return nil when an integer would be truncated in conversion.
  let input = get${Other}(${testValue})
  expectNil(${Self}(exactly: input))
}
%       end

%     end # for testValue in ...
%   end # for in all_integer_types (Other)

%   for other_type in all_floating_point_types():
%     Other = "Float" + str(other_type.bits)
%     otherMin = -int_max(bits=other_type.explicit_significand_bits, signed=False)
%     otherMax = int_max(bits=other_type.explicit_significand_bits, signed=False)

%     if Other == 'Float80':
#if !os(Windows) && (arch(i386) || arch(x86_64))
%     end

%     for testValue in [repr(value) for value in [selfMin, selfMax, selfMin - 0.1, selfMax + 0.1, otherMin, otherMax, 0.0, -0.0, 0.1, -0.1]]:

%       if testValue < otherMin or testValue > otherMax:
%         # Can't construct `other` value to test from, do nothing and continue.

%       elif testValue >= selfMin and testValue <= selfMax and testValue % 1 == 0 and testValue != -0.0:

FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
  let input = get${Other}(${testValue})
  let result = ${Self}(input)
  var resultConvertedBack = ${Other}(result)
  expectEqual(${testValue}, resultConvertedBack)
}

FloatingPointConversionFailures.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
  let input = get${Other}(${testValue})
  expectNil(${Self}(exactly: input))
}

%       else:

%         if testValue > selfMax:
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
.crashOutputMatches(getTooLargeMessage()).code {
  expectCrashLater()
%         elif testValue < selfMin:
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
.crashOutputMatches(getTooSmallMessage()).code {
  expectCrashLater()
%         else:
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
%         end
  let input = get${Other}(${testValue})
  var result = ${Self}(input)
  var resultConvertedBack = ${Other}(result)
  expectNotEqual(input, resultConvertedBack)
}

FloatingPointConversionFailures.test("${Other}To${Self}Conversion/dest=${testValue}") {
  let input = get${Other}(${testValue})
  expectNil(${Self}(exactly: input))
}
%       end
%     end # for in testValues

// Test Always-Trapping conversions.

%     if not selfSigned:

FloatingPointConversionTraps.test("${Self}/${Other}/negative")
  .crashOutputMatches(getTooSmallMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(-123.0)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/negative") {
  expectNil(${Self}(exactly: get${Other}(-123.0)))
}

%     end

FloatingPointConversionTraps.test("${Self}/${Other}/+inf")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(${Other}.infinity)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/+inf") {
  expectNil(${Self}(exactly: get${Other}(${Other}.infinity)))
}

FloatingPointConversionTraps.test("${Self}/${Other}/-inf")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(-${Other}.infinity)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/-inf") {
  expectNil(${Self}(exactly: get${Other}(-${Other}.infinity)))
}

FloatingPointConversionTraps.test("${Self}/${Other}/NaN")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(${Other}.nan)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/NaN") {
  expectNil(${Self}(exactly: get${Other}(${Other}.nan)))
}

%     if Other == 'Float80':
#endif
%     end

%   end # for in all_floating_point_types (Other)
% end # for in all_integer_types (Self)

""")

}%

#if arch(i386) || arch(arm)

  ${gyb.execute_template(
      int_to_int_conversion_template,
      word_bits=32)}

#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)

  ${gyb.execute_template(
      int_to_int_conversion_template,
      word_bits=64)}

#else

_UnimplementedError()

#endif

runAllTests()
