// Copyright (c) 2015, 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.

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_backend/no_such_method_registry.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import 'memory_compiler.dart';

class NoSuchMethodInfo {
  final String className;
  final String superClassName;
  final bool hasThrowingSyntax;
  final bool hasForwardingSyntax;
  final bool isThrowing;
  final bool isDefault;
  final bool isOther;
  final bool isNotApplicable;
  final bool isComplexNoReturn;
  final bool isComplexReturn;

  const NoSuchMethodInfo(this.className,
      {this.superClassName,
      this.hasThrowingSyntax: false,
      this.hasForwardingSyntax: false,
      this.isThrowing: false,
      this.isDefault: false,
      this.isOther: false,
      this.isNotApplicable: false,
      this.isComplexNoReturn: false,
      this.isComplexReturn: false});
}

class NoSuchMethodTest {
  final String code;
  final List<NoSuchMethodInfo> methods;
  final bool isNoSuchMethodUsed;

  const NoSuchMethodTest(this.code, this.methods,
      {this.isNoSuchMethodUsed: false});
}

const List<NoSuchMethodTest> TESTS = const <NoSuchMethodTest>[
  const NoSuchMethodTest("""
class A {
  foo() => 3;
  noSuchMethod(x) => super.noSuchMethod(x);
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
  ]),
  const NoSuchMethodTest("""
class A extends B {
  foo() => 3;
  noSuchMethod(x) => super.noSuchMethod(x);
}
class B {}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
  ]),
  const NoSuchMethodTest("""
class A extends B {
  foo() => 3;
  noSuchMethod(x) {
    return super.noSuchMethod(x);
  }
}
class B {}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
  ]),
  const NoSuchMethodTest("""
class A extends B {
  foo() => 3;
  noSuchMethod(x) => super.noSuchMethod(x);
}
class B {
  noSuchMethod(x) => super.noSuchMethod(x);
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A',
        superClassName: 'B', hasForwardingSyntax: true, isDefault: true),
    const NoSuchMethodInfo('B', hasForwardingSyntax: true, isDefault: true),
  ]),
  const NoSuchMethodTest("""
class A extends B {
  foo() => 3;
  noSuchMethod(x) => super.noSuchMethod(x);
}
class B {
  noSuchMethod(x) => throw 'foo';
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A',
        superClassName: 'B', hasForwardingSyntax: true, isThrowing: true),
    const NoSuchMethodInfo('B', hasThrowingSyntax: true, isThrowing: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(x) => 3;
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(x, [y]) => super.noSuchMethod(x);
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
  ]),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(x, [y]) => super.noSuchMethod(x, y);
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(x, y) => super.noSuchMethod(x);
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A',
        hasForwardingSyntax: true, isNotApplicable: true),
  ]),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(Invocation x) {
    throw new UnsupportedError();
  }
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasThrowingSyntax: true, isThrowing: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(Invocation x) {
    print('foo');
    throw 'foo';
  }
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(Invocation x) {
    return toString();
  }
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
  ], isNoSuchMethodUsed: true),
  const NoSuchMethodTest("""
class A {
  noSuchMethod(x) => super.noSuchMethod(x) as dynamic;
}
main() {
  print(new A().foo());
}
""", const <NoSuchMethodInfo>[
    const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
  ]),
];

main() {
  runTests({bool useKernel}) async {
    for (NoSuchMethodTest test in TESTS) {
      print('---- testing -------------------------------------------------');
      print(test.code);
      CompilationResult result = await runCompiler(
          memorySourceFiles: {'main.dart': test.code},
          options: useKernel ? [] : [Flags.useOldFrontend]);
      Compiler compiler = result.compiler;
      checkTest(compiler, test);
    }
  }

  asyncTest(() async {
    print('--test from ast---------------------------------------------------');
    await runTests(useKernel: false);
    print('--test from kernel------------------------------------------------');
    await runTests(useKernel: true);
  });
}

checkTest(Compiler compiler, NoSuchMethodTest test) {
  ElementEnvironment frontendEnvironment =
      compiler.frontendStrategy.elementEnvironment;
  NoSuchMethodRegistryImpl registry = compiler.backend.noSuchMethodRegistry;
  NoSuchMethodResolver resolver = registry.internalResolverForTesting;
  FunctionEntity ObjectNSM = frontendEnvironment.lookupClassMember(
      compiler.frontendStrategy.commonElements.objectClass, 'noSuchMethod');
  ClosedWorld backendClosedWorld = compiler.backendClosedWorldForTesting;
  ElementEnvironment backendEnvironment = backendClosedWorld.elementEnvironment;
  NoSuchMethodDataImpl data = backendClosedWorld.noSuchMethodData;

  // Test [NoSuchMethodResolver] results for each method.
  for (NoSuchMethodInfo info in test.methods) {
    ClassEntity cls = frontendEnvironment.lookupClass(
        frontendEnvironment.mainLibrary, info.className);
    Expect.isNotNull(cls, "Class ${info.className} not found.");
    FunctionEntity noSuchMethod =
        frontendEnvironment.lookupClassMember(cls, 'noSuchMethod');
    Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls.");

    if (info.superClassName == null) {
      Expect.equals(ObjectNSM, resolver.getSuperNoSuchMethod(noSuchMethod));
    } else {
      ClassEntity superclass = frontendEnvironment.lookupClass(
          frontendEnvironment.mainLibrary, info.superClassName);
      Expect.isNotNull(
          superclass, "Superclass ${info.superClassName} not found.");
      FunctionEntity superNoSuchMethod =
          frontendEnvironment.lookupClassMember(superclass, 'noSuchMethod');
      Expect.isNotNull(
          superNoSuchMethod, "noSuchMethod not found in $superclass.");
      Expect.equals(
          superNoSuchMethod,
          resolver.getSuperNoSuchMethod(noSuchMethod),
          "Unexpected super noSuchMethod for $noSuchMethod.");
    }

    Expect.equals(
        info.hasForwardingSyntax,
        resolver.hasForwardingSyntax(noSuchMethod),
        "Unexpected hasForwardSyntax result on $noSuchMethod.");
    Expect.equals(
        info.hasThrowingSyntax,
        resolver.hasThrowingSyntax(noSuchMethod),
        "Unexpected hasThrowingSyntax result on $noSuchMethod.");
  }

  // Test [NoSuchMethodRegistry] results for each method. These are based on
  // the [NoSuchMethodResolver] results which are therefore tested for all
  // methods first.
  for (NoSuchMethodInfo info in test.methods) {
    ClassEntity frontendClass = frontendEnvironment.lookupClass(
        frontendEnvironment.mainLibrary, info.className);
    Expect.isNotNull(frontendClass, "Class ${info.className} not found.");
    FunctionEntity frontendNoSuchMethod =
        frontendEnvironment.lookupClassMember(frontendClass, 'noSuchMethod');
    Expect.isNotNull(
        frontendNoSuchMethod, "noSuchMethod not found in $frontendClass.");

    Expect.equals(
        info.isDefault,
        registry.defaultImpls.contains(frontendNoSuchMethod),
        "Unexpected isDefault result on $frontendNoSuchMethod.");
    Expect.equals(
        info.isThrowing,
        registry.throwingImpls.contains(frontendNoSuchMethod),
        "Unexpected isThrowing result on $frontendNoSuchMethod.");
    Expect.equals(
        info.isOther,
        registry.otherImpls.contains(frontendNoSuchMethod),
        "Unexpected isOther result on $frontendNoSuchMethod.");
    Expect.equals(
        info.isNotApplicable,
        registry.notApplicableImpls.contains(frontendNoSuchMethod),
        "Unexpected isNotApplicable result on $frontendNoSuchMethod.");

    ClassEntity backendClass = backendEnvironment.lookupClass(
        backendEnvironment.mainLibrary, info.className);
    Expect.isNotNull(backendClass, "Class ${info.className} not found.");
    FunctionEntity backendNoSuchMethod =
        backendEnvironment.lookupClassMember(backendClass, 'noSuchMethod');
    Expect.isNotNull(
        backendNoSuchMethod, "noSuchMethod not found in $backendClass.");

    Expect.equals(
        info.isComplexNoReturn,
        data.complexNoReturnImpls.contains(backendNoSuchMethod),
        "Unexpected isComplexNoReturn result on $backendNoSuchMethod.");
    Expect.equals(
        info.isComplexReturn,
        data.complexReturningImpls.contains(backendNoSuchMethod),
        "Unexpected isComplexReturn result on $backendNoSuchMethod.");
  }

  Expect.equals(
      test.isNoSuchMethodUsed,
      backendClosedWorld.backendUsage.isNoSuchMethodUsed,
      "Unexpected isNoSuchMethodUsed result.");
}
