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

library jsinterop.abstract_test;

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/commandline_options.dart';
import '../helpers/memory_compiler.dart';

const List<Test> TESTS = const <Test>[
  const Test('Empty js-interop class.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {}

main() => new A();
''', warnings: const []),
  const Test('Js-interop class with external method.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  external method();
}

main() => new A();
'''),
  const Test(
      'Js-interop class with external method with required parameters.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  external method(a, b);
}

main() => new A();
'''),
  const Test(
      'Js-interop class with external method with optional parameters.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  external method([a, b]);
}

main() => new A();
'''),
  const Test(
      'Js-interop class with external method with optional parameters '
          'with default values.',
      '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  external method([a = 1, b = 2]);
}

main() => new A();
'''),
  const Test('Js-interop class with static method.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  static method() {}
}

main() => new A();
'''),
  const Test('Js-interop class that extends a js-interop class.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
abstract class A {
  method();
}

@JS()
class B extends A {
  external method();
}

main() => new B();
'''),
  const Test(
      'Js-interop class that extends a js-interop class, '
          'reversed declaration order.',
      '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class B extends A {
  external method();
}

@JS()
abstract class A {
  method();
}

main() => new B();
'''),
  const Test.multi(
      'Js-interop class that extends a js-interop class from a different '
      'library.',
      const {
        'main.dart': '''
@JS()
library test;

import 'package:js/js.dart';
import 'other.dart';

@JS()
class B extends A {
  external method();
}

main() => new B();
''',
        'other.dart': '''
@JS()
library other;

import 'package:js/js.dart';

@JS()
abstract class A {
  method();
}
'''
      }),
  const Test('Js-interop class that implements a regular class.', '''
@JS()
library test;

import 'package:js/js.dart';

abstract class A {
  method();
}

@JS()
class B implements A {
  external method();
}

main() => new B();
'''),
  const Test('Js-interop class that implements a js-interop class.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
abstract class A {
  method();
}

@JS()
class B implements A {
  external method();
}

main() => new B();
'''),
  const Test('Js-interop class with generative constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  external A();
}

main() => new A();
'''),
  const Test('Js-interop class with factory constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
class A {
  factory A() => null;
}

main() => new A();
'''),
  const Test('Empty anonymous js-interop class.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {}

main() => new A();
'''),
  const Test('Anonymous js-interop class with generative constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {
  external A();
}

main() => new A();
'''),
  const Test('Anonymous js-interop class with factory constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {
  factory A() => null;
}

main() => new A();
'''),
  const Test(
      'Anonymous js-interop class with external factory constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {
  external factory A();
}

main() => new A();
'''),
  const Test('External factory constructor with named parameters.', '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {
  external factory A({a, b});
}

main() => new A(a: 1);
'''),
  const Test(
      'External factory constructor with named parameters '
          'with default parameters.',
      '''
@JS()
library test;

import 'package:js/js.dart';

@JS()
@anonymous
class A {
  external factory A({a: 1, b: 2});
}

main() => new A(a: 1);
'''),
  const Test('Function-typed return type', '''
@JS()
library lib;

import 'package:js/js.dart';

@JS('func')
external int Function() func();

main() {
  func();
}
'''),
  const Test(
    'Non-external field.',
    '''
@JS()
library lib;

import 'package:js/js.dart';

@JS()
@anonymous
class B {
  int Function() callback;
}

@JS('makeB')
external B makeB();

main() {
  makeB().callback();
}
''',
    // TODO(34174): Disallow js-interop fields.
    /*errors: const [MessageKind.IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED]*/
  ),
];

void main(List<String> args) {
  asyncTest(() async {
    for (Test test in TESTS) {
      bool run = true;
      if (args.isNotEmpty) {
        run = false;
        for (String arg in args) {
          if (test.name.contains(arg)) {
            run = true;
            break;
          }
        }
      }
      if (run) {
        await runTest(test);
      }
    }
  });
}

class Test {
  final String name;
  final String _source;
  final Map<String, String> _sources;
  final List<MessageKind> errors;
  final List<MessageKind> warnings;

  const Test(this.name, this._source,
      {this.errors: const <MessageKind>[],
      this.warnings: const <MessageKind>[]})
      : _sources = null;

  const Test.multi(this.name, this._sources,
      {this.errors: const <MessageKind>[],
      this.warnings: const <MessageKind>[]})
      : _source = null;

  String get source => _source ?? _sources['main.dart'];

  Map<String, String> get sources =>
      _source != null ? {'main.dart': _source} : _sources;
}

runTest(Test test) async {
  print('==${test.name}======================================================');
  print(test.source);
  await runTestInternal(test);
}

runTestInternal(Test test) async {
  DiagnosticCollector collector = new DiagnosticCollector();
  List<String> options = <String>[];
  // TODO(redemption): Enable inlining.
  options.add(Flags.disableInlining);
  await runCompiler(
      diagnosticHandler: collector,
      options: options,
      memorySourceFiles: test.sources);
  Expect.equals(
      test.errors.length, collector.errors.length, 'Unexpected error count.');
  Expect.equals(test.warnings.length, collector.warnings.length,
      'Unexpected warning count.');
  for (int index = 0; index < test.errors.length; index++) {
    Expect.equals(test.errors[index],
        collector.errors.elementAt(index).messageKind, 'Unexpected error.');
  }
  for (int index = 0; index < test.warnings.length; index++) {
    Expect.equals(test.warnings[index],
        collector.warnings.elementAt(index).messageKind, 'Unexpected warning.');
  }
}
