// 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, Flags.useOldFrontend],
          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}");
      });
    }
  });
}
