// 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 test program testing closures.

// @dart = 2.9

import "package:expect/expect.dart";

class LocalFunctionTest {
  LocalFunctionTest()
      : field1 = 100,
        field2_ = 200 {}
  static int f(int n) {
    int a = 0;
    g(int m) {
      a = 3 * n + m + 1; // Capture parameter n and local a.
      return a;
    }

    var b = g(n);
    return a + b;
  }

  static int h(int n) {
    k(int n) {
      var a = new List(n);
      var b = new List(n);
      int i;
      for (i = 0; i < n; i++) {
        var j = i;
        a[i] = () => i; // Captured i is always n.
        b[i] = () => j; // Captured j varies from 0 to n-1.
      }
      var a_sum = 0;
      var b_sum = 0;
      for (int i = 0; i < n; i++) {
        a_sum += a[i]();
        b_sum += b[i]();
      }
      return a_sum + b_sum;
    }

    return k(n);
  }

  static int h2(int n) {
    k(int n) {
      var a = new List(n);
      var b = new List(n);
      for (int i = 0; i < n; i++) {
        var j = i;
        a[i] = () => i; // Captured i varies from 0 to n-1.
        b[i] = () => j; // Captured j varies from 0 to n-1.
      }
      var a_sum = 0;
      var b_sum = 0;
      for (int i = 0; i < n; i++) {
        a_sum += a[i]();
        b_sum += b[i]();
      }
      return a_sum + b_sum;
    }

    return k(n);
  }

  int field1;
  int field2_;
  int get field2 {
    return field2_;
  }

  void set field2(int value) {
    field2_ = value;
  }

  int method(int n) {
    incField1() {
      field1++;
    }

    incField2() {
      field2++;
    }

    for (int i = 0; i < n; i++) {
      incField1();
      incField2();
    }
    return field1 + field2;
  }

  int execute(int times, apply(int x)) {
    for (int i = 0; i < times; i++) {
      apply(i);
    }
    return field1;
  }

  int testExecute(int n) {
    execute(n, (int x) {
      field1 += x;
    });
    return field1;
  }

  static int foo(int n) {
    return -100; // Wrong foo.
  }

  static testSelfReference1(int n) {
    int foo(int n) {
      if (n == 0) {
        return 0;
      } else {
        return 1 + foo(n - 1); // Local foo, not static foo.
      }
    }

    ;
    return foo(n); // Local foo, not static foo.
  }

  static void hep(Function f) {
    f();
  }

  static testNesting(int n) {
    var a = new List(n * n);
    f0() {
      for (int i = 0; i < n; i++) {
        int vi = i;
        f1() {
          for (int j = 0; j < n; j++) {
            int vj = j;
            a[i * n + j] = () => vi * n + vj;
          }
        }

        f1();
      }
    }

    f0();
    int result = 0;
    for (int k = 0; k < n * n; k++) {
      Expect.equals(k, a[k]());
      result += a[k]();
    }
    return result;
  }

  static var field5;
  static var set_field5_func;
  static testClosureCallStatement(int x) {
    LocalFunctionTest.set_field5_func = (int n) {
      field5 = n * n;
    };
    (LocalFunctionTest.set_field5_func)(x);
    Expect.equals(x * x, LocalFunctionTest.field5);
    return true;
  }

  static testExceptions() {
    dynamic f = (int n) => n + 1;
    Expect.equals(2, f(1));
    Expect.equals(true, f is Function);
    Expect.equals(true, f is Object);
    Expect.equals(true, f.toString().startsWith("Closure"));
    bool exception_caught = false;
    try {
      f(1, 2);
    } on NoSuchMethodError catch (e) {
      exception_caught = true;
    }
    Expect.equals(true, exception_caught);
    exception_caught = false;
    try {
      f();
    } on NoSuchMethodError catch (e) {
      exception_caught = true;
    }
    Expect.equals(true, exception_caught);
    exception_caught = false;
    try {
      f.xyz(0);
    } on NoSuchMethodError catch (e) {
      exception_caught = true;
    }
    Expect.equals(true, exception_caught);

    // Overwrite closure value.
    f = 3;
    exception_caught = false;
    try {
      f(1);
    } on NoSuchMethodError catch (e) {
      exception_caught = true;
    }
    Expect.equals(true, exception_caught);

    // Do not expect any exceptions to be thrown.
    var g = ([int n = 1]) => n + 1;
    Expect.equals(2, g());
    Expect.equals(3, g(2));
  }

  static int doThis(int n, int f(int n)) {
    return f(n);
  }

  static testMain() {
    Expect.equals(2 * (3 * 2 + 2 + 1), f(2));
    Expect.equals(10 * 10 + 10 * 9 / 2, h(10));
    Expect.equals(90, h2(10));
    Expect.equals(320, new LocalFunctionTest().method(10));
    Expect.equals(145, new LocalFunctionTest().testExecute(10));
    Expect.equals(5, testSelfReference1(5));
    Expect.equals(24 * 25 / 2, testNesting(5));
    Expect.equals(true, testClosureCallStatement(7));
    Expect.equals(99, doThis(10, (n) => n * n - 1));
    testExceptions();
  }
}

main() {
  LocalFunctionTest.testMain();
}
