// 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 'dart:convert' show JSON, UTF8;
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.getUtf8SourceFile(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);
          // Using JSON.encode to add string quotes and backslashes.
          String expected = JSON.encode(
              UTF8.decode(expectedSpanText.codeUnits, allowMalformed: true));
          String actual = JSON.encode(UTF8
              .decode(strippedLocationMessage.codeUnits, allowMalformed: true));
          Expect.equals(
              expectedSpanText,
              strippedLocationMessage,
              "Unexpected span for ${message.messageKind} in\n${test.code}"
              "\nExpected: $expected"
              "\nActual  : $actual");
          kindToSpan.remove(message.messageKind);
        }
      }
      kindToSpan.forEach((MessageKind kind, _) {
        Expect.fail("Missing message kin $kind in\n${test.code}");
      });
    }
  });
}
