// Copyright (c) 2019, 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:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(TodoTest);
  });
}

@reflectiveTest
class TodoTest extends PubPackageResolutionTest {
  test_todo_multiLineComment() async {
    await assertErrorsInCode(r'''
main() {
  /* TODO: Implement */
  /* TODO: Implement*/
}
''', [
      error(TodoCode.TODO, 14, 15, text: 'TODO: Implement'),
      error(TodoCode.TODO, 38, 15, text: 'TODO: Implement'),
    ]);
  }

  test_todo_multiLineCommentWrapped() async {
    await assertErrorsInCode(r'''
main() {
  /* TODO(a): Implement something
   *  that is too long for one line
   * This line is not part of the todo
   */
  /* TODO: Implement something
   *  that is too long for one line
   * This line is not part of the todo
   */
  /* TODO(a): Implement something
   *  that is too long for one line
   *
   *  This line is not part of the todo
   */
  /* TODO: Implement something
   *  that is too long for one line
   *
   *  This line is not part of the todo
   */
}
''', [
      error(TodoCode.TODO, 14, 64,
          text: 'TODO(a): Implement something that is too long for one line'),
      error(TodoCode.TODO, 129, 61,
          text: 'TODO: Implement something that is too long for one line'),
      error(TodoCode.TODO, 241, 64,
          text: 'TODO(a): Implement something that is too long for one line'),
      error(TodoCode.TODO, 362, 61,
          text: 'TODO: Implement something that is too long for one line'),
    ]);
  }

  test_todo_singleLineComment() async {
    await assertErrorsInCode(r'''
main() {
  // TODO: Implement
}
''', [
      error(TodoCode.TODO, 14, 15, text: 'TODO: Implement'),
    ]);
  }

  test_todo_singleLineCommentDoubleCommented() async {
    // Continuations are ignored for code that looks like commented comments
    // although the original TODOs are still picked up.
    await assertErrorsInCode(r'''
main() {
//      // TODO: Implement something
//      //  that is too long for one line
//      main() {

//      // TODO: Implement something
//      // this is not a todo
//      main() {

//      // TODO: Implement something
//      main() {
}
''', [
      error(TodoCode.TODO, 20, 67,
          text: 'TODO: Implement something that is too long for one line'),
      error(TodoCode.TODO, 117, 25, text: 'TODO: Implement something'),
      error(TodoCode.TODO, 202, 25, text: 'TODO: Implement something'),
    ]);
  }

  test_todo_singleLineCommentLessIndentedContinuation() async {
    await assertErrorsInCode(r'''
main() {
  // TODO: Implement something
  //  that is too long for one line
//    this is not part of the todo
}
''', [
      error(TodoCode.TODO, 14, 61,
          text: 'TODO: Implement something that is too long for one line'),
    ]);
  }

  test_todo_singleLineCommentMoreIndentedContinuation() async {
    await assertErrorsInCode(r'''
main() {
  // TODO: Implement something
  //  that is too long for one line
  //      this is not part of the todo
}
''', [
      error(TodoCode.TODO, 14, 61,
          text: 'TODO: Implement something that is too long for one line'),
    ]);
  }

  test_todo_singleLineCommentNested() async {
    await assertErrorsInCode(r'''
main() {
  // TODO: Implement something
  //  that is too long for one line
  //  TODO: This is a seperate todo that is accidentally indented
}
''', [
      error(TodoCode.TODO, 14, 61,
          text: 'TODO: Implement something that is too long for one line'),
      error(TodoCode.TODO, 82, 59,
          text: 'TODO: This is a seperate todo that is accidentally indented'),
    ]);
  }

  test_todo_singleLineCommentWrapped() async {
    await assertErrorsInCode(r'''
main() {
  // TODO: Implement something
  //  that is too long for one line
  // this is not part of the todo

  // TODO: Implement something
  //  that is too long for one line

  //  this is not part of the todo

  // TODO: Implement something
  //  that is too long for one line
  //
  //  this is not part of the todo
}
''', [
      error(TodoCode.TODO, 14, 61,
          text: 'TODO: Implement something that is too long for one line'),
      error(TodoCode.TODO, 116, 61,
          text: 'TODO: Implement something that is too long for one line'),
      error(TodoCode.TODO, 220, 61,
          text: 'TODO: Implement something that is too long for one line'),
    ]);
  }
}
