// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.9

library sort_helper;

import "package:expect/expect.dart";

typedef Sorter = void Function(List<num>);
typedef Comparer = int Function(num, num);

class SortHelper {
  SortHelper(this.sortFunction, this.compareFunction) {}

  void run() {
    testSortIntLists();
    testSortDoubleLists();
  }

  bool isSorted(List<num> a) {
    for (int i = 1; i < a.length; i++) {
      if (compareFunction(a[i - 1], a[i]) > 0) {
        return false;
      }
    }
    return true;
  }

  void testSortIntLists() {
    var a = new List<int>(40);

    for (int i = 0; i < a.length; i++) {
      a[i] = i;
    }
    testSort(a);

    for (int i = 0; i < a.length; i++) {
      a[a.length - i - 1] = i;
    }
    testSort(a);

    for (int i = 0; i < 21; i++) {
      a[i] = 1;
    }
    for (int i = 21; i < a.length; i++) {
      a[i] = 2;
    }
    testSort(a);

    // Same with bad pivot-choices.
    for (int i = 0; i < 21; i++) {
      a[i] = 1;
    }
    for (int i = 21; i < a.length; i++) {
      a[i] = 2;
    }
    a[6] = 1;
    a[13] = 1;
    a[19] = 1;
    a[25] = 1;
    a[33] = 2;
    testSort(a);

    for (int i = 0; i < 21; i++) {
      a[i] = 2;
    }
    for (int i = 21; i < a.length; i++) {
      a[i] = 1;
    }
    testSort(a);

    // Same with bad pivot-choices.
    for (int i = 0; i < 21; i++) {
      a[i] = 2;
    }
    for (int i = 21; i < a.length; i++) {
      a[i] = 1;
    }
    a[6] = 2;
    a[13] = 2;
    a[19] = 2;
    a[25] = 2;
    a[33] = 1;
    testSort(a);

    var a2 = new List<int>(0);
    testSort(a2);

    var a3 = new List<int>(1);
    a3[0] = 1;
    testSort(a3);

    // --------
    // Test insertion sort.
    testInsertionSort(0, 1, 2, 3);
    testInsertionSort(0, 1, 3, 2);
    testInsertionSort(0, 3, 2, 1);
    testInsertionSort(0, 3, 1, 2);
    testInsertionSort(0, 2, 1, 3);
    testInsertionSort(0, 2, 3, 1);
    testInsertionSort(1, 0, 2, 3);
    testInsertionSort(1, 0, 3, 2);
    testInsertionSort(1, 2, 3, 0);
    testInsertionSort(1, 2, 0, 3);
    testInsertionSort(1, 3, 2, 0);
    testInsertionSort(1, 3, 0, 2);
    testInsertionSort(2, 0, 1, 3);
    testInsertionSort(2, 0, 3, 1);
    testInsertionSort(2, 1, 3, 0);
    testInsertionSort(2, 1, 0, 3);
    testInsertionSort(2, 3, 1, 0);
    testInsertionSort(2, 3, 0, 1);
    testInsertionSort(3, 0, 1, 2);
    testInsertionSort(3, 0, 2, 1);
    testInsertionSort(3, 1, 2, 0);
    testInsertionSort(3, 1, 0, 2);
    testInsertionSort(3, 2, 1, 0);
    testInsertionSort(3, 2, 0, 1);
  }

  void testSort(List<num> a) {
    sortFunction(a);
    Expect.isTrue(isSorted(a));
  }

  void testInsertionSort(int i1, int i2, int i3, int i4) {
    var a = new List<int>(4);
    a[0] = i1;
    a[1] = i2;
    a[2] = i3;
    a[3] = i4;
    testSort(a);
  }

  void testSortDoubleLists() {
    var a = new List<double>(40);
    for (int i = 0; i < a.length; i++) {
      a[i] = 1.0 * i + 0.5;
    }
    testSort(a);

    for (int i = 0; i < a.length; i++) {
      a[i] = 1.0 * (a.length - i) + 0.5;
    }
    testSort(a);

    for (int i = 0; i < a.length; i++) {
      a[i] = 1.5;
    }
    testSort(a);
  }

  Sorter sortFunction;
  Comparer compareFunction;
}
