// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax

var typedArrayConstructors = [
  Uint8Array,
  Int8Array,
  Uint16Array,
  Int16Array,
  Uint32Array,
  Int32Array,
  Uint8ClampedArray,
  Float32Array,
  Float64Array
];

function assertArrayLikeEquals(value, expected, type) {
  assertEquals(value.__proto__, type.prototype);
  // Don't test value.length because we mess with that;
  // instead in certain callsites we check that length
  // is set appropriately.
  for (var i = 0; i < expected.length; ++i) {
    // Use Object.is to differentiate between +-0
    assertSame(expected[i], value[i]);
  }
}

for (var constructor of typedArrayConstructors) {
  // Test default numerical sorting order
  var a = new constructor([100, 7, 45])
  assertEquals(a.sort(), a);
  assertArrayLikeEquals(a, [7, 45, 100], constructor);
  assertEquals(a.length, 3);

  // For arrays of floats, certain handling of +-0/NaN
  if (constructor === Float32Array || constructor === Float64Array) {
    var b = new constructor([+0, -0, NaN, -0, NaN, +0])
    b.sort();
    assertArrayLikeEquals(b, [-0, -0, +0, +0, NaN, NaN], constructor);
    assertEquals(b.length, 6);
  }

  // Custom sort--backwards
  a.sort(function(x, y) { return y - x; });
  assertArrayLikeEquals(a, [100, 45, 7], constructor);

  // Basic TypedArray method properties:
  // Length field is ignored
  Object.defineProperty(a, 'length', {value: 1});
  assertEquals(a.sort(), a);
  assertArrayLikeEquals(a, [7, 45, 100], constructor);
  assertEquals(a.length, 1);
  // Method doesn't work on other objects
  assertThrows(function() { a.sort.call([]); }, TypeError);

  // Do not touch elements out of byte offset
  var buf = new ArrayBuffer(constructor.BYTES_PER_ELEMENT * 3);
  var a = new constructor(buf, constructor.BYTES_PER_ELEMENT);
  var b = new constructor(buf);
  b[0] = 3; b[1] = 2; b[2] = 1;
  a.sort();
  assertArrayLikeEquals(a, [1, 2], constructor);

  // Detached Operation
  var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  %ArrayBufferDetach(array.buffer);
  assertThrows(() => array.sort(), TypeError);
}

// Check that TypedArray.p.sort is stable.
for (let constructor of typedArrayConstructors) {
  // Sort an array [0..kSize-1] modulo 4. If the sort is stable, the array
  // will be partitioned into 4 parts, where each part has only increasing
  // elements.
  const kSize = 128;
  const kModulo = 4;
  const kRunSize = kSize / kModulo;

  const template = Array.from({ length: kSize }, (_, i) => i);
  const array = new constructor(template);

  const compare = (a, b) => (b % kModulo) - (a % kModulo);
  array.sort(compare);

  function assertIncreasing(from) {
    for (let i = from + 1; i < from + kRunSize; ++i) {
      assertTrue(array[i - 1] < array[i]);
      assertEquals(array[i - 1] % kModulo, array[i] % kModulo);
    }
  }

  for (let i = 0; i < kModulo; ++i) assertIncreasing(i * kRunSize);
}

// The following creates a test for each typed element kind, where the array
// to sort consists of some max/min/zero elements.
//
// When providing a custom compare function, the torque version of
// TypedArray.p.sort needs to convert array elements to "Number"/"BigInt"
// and back. The following test checks the edge cases for that conversion.

let constructorsWithArrays = [
  {ctor: Uint8Array, array: [255, 254, 4, 3, 2, 1, 0]},
  {ctor: Int8Array, array: [127, 126, 1, 0, -1, -127, -128]},
  {ctor: Uint16Array, array: [2 ** 16 - 1, 2 ** 16 - 2, 4, 3, 2, 1, 0]},
  {
    ctor: Int16Array,
    array: [2 ** 15 - 1, 2 ** 15 - 2, 1, 0, -1, -(2 ** 15 - 1), -(2 ** 15)]
  },
  {ctor: Uint32Array, array: [2 ** 32 - 1, 2 ** 32 - 2, 4, 3, 2, 1, 0]},
  {
    ctor: Int32Array,
    array: [2 ** 31 - 1, 2 ** 31 - 2, 1, 0, -1, -(2 ** 31 - 1), -(2 ** 31)]
  },
  {
    ctor: Float32Array,
    array: [2 ** 24, 2 ** 24 - 1, 1, 0,-1, -(2 ** 24 - 1), -(2 ** 24)]
  },
  {
    ctor: Float64Array,
    array: [2 ** 53, 2 ** 53 - 1, 1, 0, -1, -(2 ** 53 - 1), -(2 ** 53)]
  },
  {ctor: Uint8ClampedArray, array: [255, 254, 4, 3, 2, 1, 0]},
  {
    ctor: BigUint64Array,
    array: [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n]
  },
  {
    ctor: BigInt64Array,
    array: [2n ** 63n - 1n, 2n ** 63n - 2n, 1n, 0n,
            -1n, -(2n ** 63n - 1n), -(2n ** 63n)]
  }
];

// Compare function needs to return a Number in all cases, and not a BigInt.
// Hence we can not simply return "a - b".
function cmpfn(a, b) {
  if (a < b) return -1;
  if (b < a) return 1;
  return 0;
}

for (let constructor of constructorsWithArrays) {
  let array = new constructor.ctor(constructor.array);

  assertEquals(array.sort(cmpfn), array);
  assertArrayLikeEquals(array, constructor.array.reverse(), constructor.ctor);
  assertEquals(array.length, constructor.array.length);
}
