// 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.

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 'package:compiler/src/util/memory_compiler.dart';

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

import 'package:js/js.dart';

@JS()
class A {}

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

import 'package:js/js.dart';

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

main() => A();
'''),
  const SingleTest(
      '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() => A();
'''),
  const SingleTest(
      '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() => A();
'''),
  const SingleTest(
      '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() => A();
'''),
  const SingleTest('Js-interop class with static method.', '''
@JS()
library test;

import 'package:js/js.dart';

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

main() => A();
'''),
  const SingleTest('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() => B();
'''),
  const SingleTest(
      '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() => B();
'''),
  const MultiTest(
      '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() => B();
''',
        'other.dart': '''
@JS()
library other;

import 'package:js/js.dart';

@JS()
abstract class A {
  method();
}
'''
      }),
  const SingleTest('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() => B();
'''),
  const SingleTest('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() => B();
'''),
  const SingleTest('Js-interop class with generative constructor.', '''
@JS()
library test;

import 'package:js/js.dart';

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

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

import 'package:js/js.dart';

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

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

import 'package:js/js.dart';

@JS()
@anonymous
class A {}

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

import 'package:js/js.dart';

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

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

import 'package:js/js.dart';

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

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

import 'package:js/js.dart';

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

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

import 'package:js/js.dart';

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

main() => A(a: 1);
'''),
  const SingleTest(
      '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() => A(a: 1);
'''),
  const SingleTest('Function-typed return type', '''
@JS()
library lib;

import 'package:js/js.dart';

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

main() {
  func();
}
'''),
  const SingleTest(
    '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);
      }
    }
  });
}

abstract class Test {
  final String name;
  final List<MessageKind> errors;
  final List<MessageKind> warnings;

  const Test(this.name, {required this.errors, required this.warnings});
  String get source;
  Map<String, String> get sources;
}

class SingleTest extends Test {
  @override
  final String source;

  const SingleTest(super.name, this.source,
      {super.errors = const <MessageKind>[],
      super.warnings = const <MessageKind>[]});

  @override
  Map<String, String> get sources => {'main.dart': source};
}

class MultiTest extends Test {
  @override
  final Map<String, String> sources;

  const MultiTest(super.name, this.sources,
      {super.errors = const <MessageKind>[],
      super.warnings = const <MessageKind>[]});

  @override
  String get source => sources['main.dart']!;
}

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

runTestInternal(Test test) async {
  DiagnosticCollector collector = 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.');
  }
}
