// 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 that NoSuchMethod is properly called.

import "package:expect/expect.dart";

class Cat {
  bool eatFood(String food) => true;
  String scratch(String furniture) => 'purr';
  String mood;
}

class MockCat implements Cat {
  dynamic noSuchMethod(Invocation invocation) {
    var arg = invocation.positionalArguments[0];
    return arg is String && arg.isNotEmpty;
  }
}

class MockCat2 extends MockCat {
  // this apparently works.
  noSuchMethod(_);
}

class MockCat3 extends MockCat2 implements Cat {
  bool eatFood(String food, {double amount});
  String scratch(String furniture, [String furniture2]);

  dynamic noSuchMethod(Invocation invocation) {
    if (invocation.memberName == #scratch) {
      return invocation.positionalArguments.join(',');
    }

    return (invocation.positionalArguments[0] as String).isNotEmpty &&
        invocation.namedArguments[#amount] > 0.5;
  }
}

class MockWithGenerics {
  List<Type> doStuff<T>(T t);

  noSuchMethod(i) => (i as dynamic).typeArguments;
}

class MockWithGetterSetter {
  get getter;
  set setter(value);

  Invocation invocation;
  noSuchMethod(i) {
    invocation = i;
  }
}

class Callable {
  int call() => 1;
  int m() => 2;
}

class MockCallable implements Callable {
  noSuchMethod(i) => i.memberName == #call ? 42 : 0;
}

void main() {
  MockCat mock = new MockCat();
  Expect.isTrue((mock as dynamic).eatFood("cat food"));
  Expect.isFalse(mock.eatFood(""));
  mock.mood = 'sleepy';
  (mock as dynamic).mood = 'playful';
  Expect.throwsTypeError(() {
    (mock as dynamic).mood = 42;
  });

  // In strong mode this will be a runtime type error:
  // bool is not a String. VM will fail with noSuchMethod +.
  Expect.throws(() => mock.scratch("couch") + '');

  var mock2 = new MockCat2();
  Expect.isTrue(mock2.eatFood("cat food"));

  var mock3 = new MockCat3();
  Expect.isTrue(mock3.eatFood("cat food", amount: 0.9));
  Expect.isFalse(mock3.eatFood("cat food", amount: 0.3));
  Expect.equals("chair", mock3.scratch("chair"));
  Expect.equals("chair,couch", mock3.scratch("chair", "couch"));
  Expect.equals("chair,null", mock3.scratch("chair", null));
  Expect.equals("chair,", mock3.scratch("chair", ""));

  var g = new MockWithGenerics();
  Expect.listEquals([int], g.doStuff(42));
  Expect.listEquals([num], g.doStuff<num>(42));
  Expect.listEquals([String], g.doStuff('hi'));

  var s = new MockWithGetterSetter();
  s.getter;
  Expect.equals(0, s.invocation.positionalArguments.length);
  Expect.isTrue(s.invocation.isGetter);
  Expect.isFalse(s.invocation.isSetter);
  Expect.isFalse(s.invocation.isMethod);
  s.setter = 42;
  Expect.equals(42, s.invocation.positionalArguments.single);
  Expect.isFalse(s.invocation.isGetter);
  Expect.isTrue(s.invocation.isSetter);
  Expect.isFalse(s.invocation.isMethod);

  testMockTearoffs();
  testMockCallable();
  testMockCallableTearoff();
}

testMockCallable() {
  Callable call = new MockCallable();
  Expect.equals(42, call());
  Expect.equals(42, (call as dynamic)());
  Expect.equals(0, call.m());
  Expect.equals(0, (call as dynamic).m());
}

testMockCallableTearoff() {
  var mock = new MockCallable();
  Function f = mock;
  Expect.equals(42, f());
  Expect.equals(42, (f as dynamic)());
  Expect.equals(f, mock.call);
  Expect.equals(f.call, mock.call);
  Expect.equals((f as dynamic).call, mock.call);
  Expect.equals(f.call, (mock as dynamic).call);
}

typedef bool EatFoodType(String food);

testMockTearoffs() {
  var mock2 = new MockCat2();
  var eat = mock2.eatFood;
  var eat2 = (mock2 as dynamic).eatFood;

  Expect.isTrue(eat is EatFoodType, 'eat is EatFoodType');
  Expect.isTrue(eat2 is EatFoodType, 'eat2 is EatFoodType');
  Expect.equals(eat, eat2, 'eat == eat2');
  Expect.isTrue(eat.runtimeType == eat2.runtimeType,
      'eat.runtimeType == eat2.runtimeType');

  Expect.isTrue(eat("cat food"), 'eat("cat food")');
  Expect.isFalse(eat(""), 'eat("")');
  Expect.isTrue(eat2("cat food"), 'eat2("cat food")');
  Expect.isFalse(eat2(""), 'eat2("")');

  var g = new MockWithGenerics();
  var doStuff = g.doStuff;
  var doStuff2 = (g as dynamic).doStuff;

  Expect.equals(doStuff, doStuff2, 'doStuff == doStuff2');
  Expect.equals(doStuff.runtimeType, doStuff2.runtimeType,
      'doStuff.runtimeType == doStuff2.runtimeType');

  Expect.listEquals([int], doStuff(42));
  Expect.listEquals([num], doStuff<num>(42));
  Expect.listEquals([String], doStuff('hi'));

  // no inference happens because `doStuff2` is dynamic.
  Expect.listEquals([num], doStuff2<num>(42));
  expectIsDynamicOrObject(List types) {
    Expect.equals(1, types.length);
    var t = types[0];
    // TODO(jmesserly): allows either type because of
    // https://github.com/dart-lang/sdk/issues/32483
    Expect.isTrue(t == dynamic || t == Object, '$t == dynamic || $t == Object');
  }

  expectIsDynamicOrObject(doStuff2(42));
  expectIsDynamicOrObject(doStuff2('hi'));
}
