// 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.
//
// Test named arguments work as expected regardless of whether the function or
// method is called via function call syntax or method call syntax.
// VMOptions=--optimization-counter-threshold=10

import "package:expect/expect.dart";


Validate(tag, a, b) {
  // tag encodes which parameters are passed in with values a: 111, b: 222.
  if (tag == 'ab') {
    Expect.equals(a, 111);
    Expect.equals(b, 222);
  }
  if (tag == 'a') {
    Expect.equals(a, 111);
    Expect.equals(b, 20);
  }
  if (tag == 'b') {
    Expect.equals(a, 10);
    Expect.equals(b, 222);
  }
  if (tag == '') {
    Expect.equals(a, 10);
    Expect.equals(b, 20);
  }
}

class HasMethod {

  int calls;

  HasMethod() : calls = 0 {}

  foo(tag, [a = 10, b = 20]) {
    calls += 1;
    Validate(tag, a, b);
  }

  foo2(tag, {a: 10, b: 20}) {
    calls += 1;
    Validate(tag, a, b);
  }
}

class HasField {

  int calls;
  var foo, foo2;

  HasField() {
    calls = 0;
    foo = makeFoo(this);
    foo2 = makeFoo2(this);
  }

  makeFoo(owner) {
    // This function is closed-over 'owner'.
    return (tag, [a = 10, b = 20]) {
      owner.calls += 1;
      Validate(tag, a, b);
    };
  }

  makeFoo2(owner) {
    // This function is closed-over 'owner'.
    return (tag, {a: 10, b: 20}) {
      owner.calls += 1;
      Validate(tag, a, b);
    };
  }
}


class NamedParametersWithConversionsTest {

  static checkException(thunk) {
    bool threw = false;
    try {
      thunk();
    } catch (e) {
      threw = true;
    }
    Expect.isTrue(threw);
  }

  static testMethodCallSyntax(a) {
    a.foo('');
    a.foo('a', 111);
    a.foo('ab', 111, 222);
    a.foo2('a', a: 111);
    a.foo2('b', b: 222);
    a.foo2('ab', a: 111, b: 222);
    a.foo2('ab', b: 222, a: 111);

    Expect.equals(7, a.calls);

    checkException(() => a.foo()); //                  Too few arguments.
    checkException(() => a.foo('abc', 1, 2, 3)); //    Too many arguments.
    checkException(() => a.foo2('c', c: 1)); //        Bad name.
    checkException(() => a.foo2('c', a:111, c: 1)); // Bad name.

    Expect.equals(7, a.calls);
  }

  static testFunctionCallSyntax(a) {
    var f = a.foo;
    var f2 = a.foo2;
    f('');
    f('a', 111);
    f('ab', 111, 222);
    f2('a', a: 111);
    f2('b', b: 222);
    f2('ab', a: 111, b: 222);
    f2('ab', b: 222, a: 111);

    Expect.equals(7, a.calls);

    checkException(() => f()); //                   Too few arguments.
    checkException(() => f('abc', 1, 2, 3)); //     Too many arguments.
    checkException(() => f2('c', c: 1)); //         Bad name.
    checkException(() => f2('c', a: 111, c: 1)); // Bad name.

    Expect.equals(7, a.calls);
  }

  static testMain() {
    // 'Plain' calls where the method/field syntax matches the object.
    testMethodCallSyntax(new HasMethod());
    testFunctionCallSyntax(new HasField());

    // 'Conversion' calls where method/field call syntax does not match the
    // object.
    testMethodCallSyntax(new HasField());
    testFunctionCallSyntax(new HasMethod());
  }
}

main() {
  for (var i = 0; i < 20; i++) {
    NamedParametersWithConversionsTest.testMain();
  }
}
