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

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:expect/expect.dart';
import 'memory_compiler.dart';
import 'memory_source_file_helper.dart';

const List<Test> TESTS = const <Test>[
  const Test('''
class A { A(b); }
class B extends A {
  a() {}

  lot() {}

  of() {}

  var members;
}
main() => new B();''',
  const {
    MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A {
^^^^^^^^^^^^^^^^^'''}),

  const Test('''
class I {}
class A { A(b); }
class B extends A implements I {
  a() {}

  lot() {}

  of() {}

  var members;
}
main() => new B();''',
  const {
    MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A implements I {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''}),

  const Test('''
class M<T> {}
class A { A(b); }
class B extends A with M<int> {
  a() {}

  lot() {}

  of() {}

  var members;
}
main() => new B();''',
  const {
    MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A with M<int> {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''}),

  const Test('''
class A { A(b); }
class B
    extends A {
  a() {}

  lot() {}

  of() {}

  var members;
}
main() => new B();''',
  const {
    MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B
    extends A {
'''}),

  const Test('''
void foo(int a) {
  // a
  // non-empty
  // body
}
main() => foo('');''',
  const {
    MessageKind.THIS_IS_THE_METHOD: '''
void foo(int a) {
^^^^^^^^^^^^^^^'''}),

  const Test('''
void foo(int a,
         int b) {
  // a
  // non-empty
  // body
}
main() => foo('', 0);''',
  const {
    MessageKind.THIS_IS_THE_METHOD: '''
void foo(int a,
         int b) {
'''}),

  const Test('''
class A {
  int foo() {
    // a
    // non-empty
    // body
  }
}
class B extends A {
  int get foo {
    // a
    // non-empty
    // body
    return 0;
  }
}
main() => new B();''',
  const {
    MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER: '''
  int get foo {
  ^^^^^^^^^^^''',
    MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT: '''
  int foo() {
  ^^^^^^^^^'''}),
];

class Test {
  final String code;
  final Map<MessageKind, String> kindToSpan;

  const Test(this.code, this.kindToSpan);
}

const String MARKER = '---marker---';

main() {
  asyncTest(() async {
    var cachedCompiler;
    for (Test test in TESTS) {
      DiagnosticCollector collector = new DiagnosticCollector();
      CompilationResult result = await runCompiler(
          memorySourceFiles: {'main.dart': test.code},
          options: [Flags.analyzeOnly],
          diagnosticHandler: collector,
          cachedCompiler: cachedCompiler);
      cachedCompiler = result.compiler;
      MemorySourceFileProvider provider = cachedCompiler.provider;
      Map<MessageKind, String> kindToSpan =
          new Map<MessageKind, String>.from(test.kindToSpan);
      for (CollectedMessage message in collector.messages) {
        String expectedSpanText = kindToSpan[message.messageKind];
        if (expectedSpanText != null) {
          SourceFile sourceFile = provider.getSourceFile(message.uri);
          String locationMessage =
              sourceFile.getLocationMessage(MARKER, message.begin, message.end);
          // Remove `filename:line:column:` and message.
          String strippedLocationMessage = locationMessage.substring(
              locationMessage.indexOf(MARKER) + MARKER.length + 1);
          Expect.equals(expectedSpanText, strippedLocationMessage,
              "Unexpected span for ${message.messageKind} in\n${test.code}"
              "\nExpected:${expectedSpanText.codeUnits}"
              "\nActual  :${strippedLocationMessage.codeUnits}");
          kindToSpan.remove(message.messageKind);
        }
      }
      kindToSpan.forEach((MessageKind kind, _) {
        Expect.fail("Missing message kin $kind in\n${test.code}");
      });
    }
  });
}