// Copyright (c) 2017, 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/dart/ast/ast.dart' as analyzer;
import 'package:analyzer/dart/element/element.dart' as analyzer;
import 'package:analyzer/dart/element/type.dart' as analyzer;
import 'package:analyzer/error/error.dart' as analyzer;
import 'package:analyzer/exception/exception.dart' as analyzer;
import 'package:analyzer/source/error_processor.dart' as analyzer;
import 'package:analyzer/src/dart/element/element.dart' as analyzer;
import 'package:analyzer/src/error/codes.dart' as analyzer;
import 'package:analyzer/src/generated/engine.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart' as analyzer;
import 'package:analyzer/src/generated/utilities_dart.dart' as analyzer;
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../support/abstract_context.dart';

void main() {
  defineReflectiveTests(AnalyzerConverterTest);
}

@reflectiveTest
class AnalyzerConverterTest extends AbstractContextTest {
  AnalyzerConverter converter = new AnalyzerConverter();
  analyzer.Source source;
  String testFile;

  /**
   * Assert that the given [pluginError] matches the given [analyzerError].
   */
  void assertError(
      plugin.AnalysisError pluginError, analyzer.AnalysisError analyzerError,
      {analyzer.ErrorSeverity severity,
      int startColumn: -1,
      int startLine: -1}) {
    analyzer.ErrorCode errorCode = analyzerError.errorCode;
    expect(pluginError, isNotNull);
    plugin.Location location = pluginError.location;
    expect(pluginError.code, errorCode.name.toLowerCase());
    expect(pluginError.correction, errorCode.correction);
    expect(location, isNotNull);
    expect(location.file, analyzerError.source.fullName);
    expect(location.length, analyzerError.length);
    expect(location.offset, analyzerError.offset);
    expect(location.startColumn, startColumn);
    expect(location.startLine, startLine);
    expect(pluginError.message, errorCode.message);
    expect(pluginError.severity,
        converter.convertErrorSeverity(severity ?? errorCode.errorSeverity));
    expect(pluginError.type, converter.convertErrorType(errorCode.type));
  }

  analyzer.AnalysisError createError(int offset) => new analyzer.AnalysisError(
      source, offset, 5, analyzer.CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT);

  @override
  void setUp() {
    super.setUp();
    source = provider
        .newFile(provider.convertPath('/foo/bar.dart'), '')
        .createSource();
    testFile = provider.convertPath('/test.dart');
  }

  test_convertAnalysisError_lineInfo_noSeverity() {
    analyzer.AnalysisError analyzerError = createError(13);
    analyzer.LineInfo lineInfo = new analyzer.LineInfo([0, 10, 20]);

    assertError(
        converter.convertAnalysisError(analyzerError, lineInfo: lineInfo),
        analyzerError,
        startColumn: 4,
        startLine: 2);
  }

  test_convertAnalysisError_lineInfo_severity() {
    analyzer.AnalysisError analyzerError = createError(13);
    analyzer.LineInfo lineInfo = new analyzer.LineInfo([0, 10, 20]);
    analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;

    assertError(
        converter.convertAnalysisError(analyzerError,
            lineInfo: lineInfo, severity: severity),
        analyzerError,
        startColumn: 4,
        startLine: 2,
        severity: severity);
  }

  test_convertAnalysisError_noLineInfo_noSeverity() {
    analyzer.AnalysisError analyzerError = createError(11);

    assertError(converter.convertAnalysisError(analyzerError), analyzerError);
  }

  test_convertAnalysisError_noLineInfo_severity() {
    analyzer.AnalysisError analyzerError = createError(11);
    analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;

    assertError(
        converter.convertAnalysisError(analyzerError, severity: severity),
        analyzerError,
        severity: severity);
  }

  test_convertAnalysisErrors_lineInfo_noOptions() {
    List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
      createError(13),
      createError(25)
    ];
    analyzer.LineInfo lineInfo = new analyzer.LineInfo([0, 10, 20]);

    List<plugin.AnalysisError> pluginErrors =
        converter.convertAnalysisErrors(analyzerErrors, lineInfo: lineInfo);
    expect(pluginErrors, hasLength(analyzerErrors.length));
    assertError(pluginErrors[0], analyzerErrors[0],
        startColumn: 4, startLine: 2);
    assertError(pluginErrors[1], analyzerErrors[1],
        startColumn: 6, startLine: 3);
  }

  test_convertAnalysisErrors_lineInfo_options() {
    List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
      createError(13),
      createError(25)
    ];
    analyzer.LineInfo lineInfo = new analyzer.LineInfo([0, 10, 20]);
    analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;
    analyzer.AnalysisOptionsImpl options = new analyzer.AnalysisOptionsImpl();
    options.errorProcessors = [
      new analyzer.ErrorProcessor(analyzerErrors[0].errorCode.name, severity)
    ];

    List<plugin.AnalysisError> pluginErrors = converter.convertAnalysisErrors(
        analyzerErrors,
        lineInfo: lineInfo,
        options: options);
    expect(pluginErrors, hasLength(analyzerErrors.length));
    assertError(pluginErrors[0], analyzerErrors[0],
        startColumn: 4, startLine: 2, severity: severity);
    assertError(pluginErrors[1], analyzerErrors[1],
        startColumn: 6, startLine: 3, severity: severity);
  }

  test_convertAnalysisErrors_noLineInfo_noOptions() {
    List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
      createError(11),
      createError(25)
    ];

    List<plugin.AnalysisError> pluginErrors =
        converter.convertAnalysisErrors(analyzerErrors);
    expect(pluginErrors, hasLength(analyzerErrors.length));
    assertError(pluginErrors[0], analyzerErrors[0]);
    assertError(pluginErrors[1], analyzerErrors[1]);
  }

  test_convertAnalysisErrors_noLineInfo_options() {
    List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
      createError(13),
      createError(25)
    ];
    analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;
    analyzer.AnalysisOptionsImpl options = new analyzer.AnalysisOptionsImpl();
    options.errorProcessors = [
      new analyzer.ErrorProcessor(analyzerErrors[0].errorCode.name, severity)
    ];

    List<plugin.AnalysisError> pluginErrors =
        converter.convertAnalysisErrors(analyzerErrors, options: options);
    expect(pluginErrors, hasLength(analyzerErrors.length));
    assertError(pluginErrors[0], analyzerErrors[0], severity: severity);
    assertError(pluginErrors[1], analyzerErrors[1], severity: severity);
  }

  test_convertElement_class() async {
    analyzer.Source source = addSource(testFile, '''
@deprecated
abstract class _A {}
class B<K, V> {}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    {
      analyzer.ClassElement engineElement = findElementInUnit(unit, '_A');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.CLASS);
      expect(element.name, '_A');
      expect(element.typeParameters, isNull);
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, 27);
        expect(location.length, '_A'.length);
        expect(location.startLine, 2);
        expect(location.startColumn, 16);
      }
      expect(element.parameters, isNull);
      expect(
          element.flags,
          plugin.Element.FLAG_ABSTRACT |
              plugin.Element.FLAG_DEPRECATED |
              plugin.Element.FLAG_PRIVATE);
    }
    {
      analyzer.ClassElement engineElement = findElementInUnit(unit, 'B');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.CLASS);
      expect(element.name, 'B');
      expect(element.typeParameters, '<K, V>');
      expect(element.flags, 0);
    }
  }

  test_convertElement_constructor() async {
    analyzer.Source source = addSource(testFile, '''
class A {
  const A.myConstructor(int a, [String b]);
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.ConstructorElement engineElement =
        findElementInUnit(unit, 'myConstructor');
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.CONSTRUCTOR);
    expect(element.name, 'myConstructor');
    expect(element.typeParameters, isNull);
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 20);
      expect(location.length, 'myConstructor'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 11);
    }
    expect(element.parameters, '(int a, [String b])');
    expect(element.returnType, 'A');
    expect(element.flags, plugin.Element.FLAG_CONST);
  }

  void test_convertElement_dynamic() {
    var engineElement = analyzer.DynamicElementImpl.instance;
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.UNKNOWN);
    expect(element.name, 'dynamic');
    expect(element.location, isNull);
    expect(element.parameters, isNull);
    expect(element.returnType, isNull);
    expect(element.flags, 0);
  }

  test_convertElement_enum() async {
    analyzer.Source source = addSource(testFile, '''
@deprecated
enum _E1 { one, two }
enum E2 { three, four }''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    {
      analyzer.ClassElement engineElement = findElementInUnit(unit, '_E1');
      expect(engineElement.hasDeprecated, isTrue);
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.ENUM);
      expect(element.name, '_E1');
      expect(element.typeParameters, isNull);
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, 17);
        expect(location.length, '_E1'.length);
        expect(location.startLine, 2);
        expect(location.startColumn, 6);
      }
      expect(element.parameters, isNull);
      expect(
          element.flags,
          (engineElement.hasDeprecated ? plugin.Element.FLAG_DEPRECATED : 0) |
              plugin.Element.FLAG_PRIVATE);
    }
    {
      analyzer.ClassElement engineElement = findElementInUnit(unit, 'E2');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.ENUM);
      expect(element.name, 'E2');
      expect(element.typeParameters, isNull);
      expect(element.flags, 0);
    }
  }

  test_convertElement_enumConstant() async {
    analyzer.Source source = addSource(testFile, '''
@deprecated
enum _E1 { one, two }
enum E2 { three, four }''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    {
      analyzer.FieldElement engineElement = findElementInUnit(unit, 'one');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
      expect(element.name, 'one');
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, 23);
        expect(location.length, 'one'.length);
        expect(location.startLine, 2);
        expect(location.startColumn, 12);
      }
      expect(element.parameters, isNull);
      expect(element.returnType, '_E1');
      // TODO(danrubel) determine why enum constant is not marked as deprecated
      //analyzer.ClassElement classElement = engineElement.enclosingElement;
      //expect(classElement.isDeprecated, isTrue);
      expect(
          element.flags,
          // Element.FLAG_DEPRECATED |
          plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
    }
    {
      analyzer.FieldElement engineElement = findElementInUnit(unit, 'three');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
      expect(element.name, 'three');
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, 44);
        expect(location.length, 'three'.length);
        expect(location.startLine, 3);
        expect(location.startColumn, 11);
      }
      expect(element.parameters, isNull);
      expect(element.returnType, 'E2');
      expect(element.flags,
          plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
    }
    {
      analyzer.FieldElement engineElement =
          unit.declaredElement.enums[1].getField('index');
      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.FIELD);
      expect(element.name, 'index');
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, -1);
        expect(location.length, 'index'.length);
        expect(location.startLine, 1);
        expect(location.startColumn, 0);
      }
      expect(element.parameters, isNull);
      expect(element.returnType, 'int');
      expect(element.flags, plugin.Element.FLAG_FINAL);
    }
    {
      analyzer.FieldElement engineElement =
          unit.declaredElement.enums[1].getField('values');

      // create notification Element
      plugin.Element element = converter.convertElement(engineElement);
      expect(element.kind, plugin.ElementKind.FIELD);
      expect(element.name, 'values');
      {
        plugin.Location location = element.location;
        expect(location.file, testFile);
        expect(location.offset, -1);
        expect(location.length, 'values'.length);
        expect(location.startLine, 1);
        expect(location.startColumn, 0);
      }
      expect(element.parameters, isNull);
      expect(element.returnType, 'List<E2>');
      expect(element.flags,
          plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
    }
  }

  test_convertElement_field() async {
    analyzer.Source source = addSource(testFile, '''
class A {
  static const myField = 42;
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.FieldElement engineElement = findElementInUnit(unit, 'myField');
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.FIELD);
    expect(element.name, 'myField');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 25);
      expect(location.length, 'myField'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 16);
    }
    expect(element.parameters, isNull);
    expect(element.returnType, 'int');
    expect(
        element.flags, plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
  }

  test_convertElement_functionTypeAlias() async {
    analyzer.Source source = addSource(testFile, '''
typedef int F<T>(String x);
''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.FunctionTypeAliasElement engineElement =
        findElementInUnit(unit, 'F');
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.FUNCTION_TYPE_ALIAS);
    expect(element.name, 'F');
    expect(element.typeParameters, '<T>');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 12);
      expect(location.length, 'F'.length);
      expect(location.startLine, 1);
      expect(location.startColumn, 13);
    }
    expect(element.parameters, '(String x)');
    expect(element.returnType, 'int');
    expect(element.flags, 0);
  }

  test_convertElement_getter() async {
    analyzer.Source source = addSource(testFile, '''
class A {
  String get myGetter => 42;
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.PropertyAccessorElement engineElement =
        findElementInUnit(unit, 'myGetter', analyzer.ElementKind.GETTER);
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.GETTER);
    expect(element.name, 'myGetter');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 23);
      expect(location.length, 'myGetter'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 14);
    }
    expect(element.parameters, isNull);
    expect(element.returnType, 'String');
    expect(element.flags, 0);
  }

  test_convertElement_method() async {
    analyzer.Source source = addSource(testFile, '''
class A {
  static List<String> myMethod(int a, {String b, int c}) {
    return null;
  }
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.MethodElement engineElement = findElementInUnit(unit, 'myMethod');
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.METHOD);
    expect(element.name, 'myMethod');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 32);
      expect(location.length, 'myGetter'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 23);
    }
    expect(element.parameters, '(int a, {String b, int c})');
    expect(element.returnType, 'List<String>');
    expect(element.flags, plugin.Element.FLAG_STATIC);
  }

  test_convertElement_setter() async {
    analyzer.Source source = addSource(testFile, '''
class A {
  set mySetter(String x) {}
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.PropertyAccessorElement engineElement =
        findElementInUnit(unit, 'mySetter', analyzer.ElementKind.SETTER);
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.SETTER);
    expect(element.name, 'mySetter');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 16);
      expect(location.length, 'mySetter'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 7);
    }
    expect(element.parameters, '(String x)');
    expect(element.returnType, isNull);
    expect(element.flags, 0);
  }

  void test_convertElementKind() {
    expect(converter.convertElementKind(analyzer.ElementKind.CLASS),
        plugin.ElementKind.CLASS);
    expect(converter.convertElementKind(analyzer.ElementKind.COMPILATION_UNIT),
        plugin.ElementKind.COMPILATION_UNIT);
    expect(converter.convertElementKind(analyzer.ElementKind.CONSTRUCTOR),
        plugin.ElementKind.CONSTRUCTOR);
    expect(converter.convertElementKind(analyzer.ElementKind.FIELD),
        plugin.ElementKind.FIELD);
    expect(converter.convertElementKind(analyzer.ElementKind.FUNCTION),
        plugin.ElementKind.FUNCTION);
    expect(
        converter.convertElementKind(analyzer.ElementKind.FUNCTION_TYPE_ALIAS),
        plugin.ElementKind.FUNCTION_TYPE_ALIAS);
    expect(converter.convertElementKind(analyzer.ElementKind.GETTER),
        plugin.ElementKind.GETTER);
    expect(converter.convertElementKind(analyzer.ElementKind.LABEL),
        plugin.ElementKind.LABEL);
    expect(converter.convertElementKind(analyzer.ElementKind.LIBRARY),
        plugin.ElementKind.LIBRARY);
    expect(converter.convertElementKind(analyzer.ElementKind.LOCAL_VARIABLE),
        plugin.ElementKind.LOCAL_VARIABLE);
    expect(converter.convertElementKind(analyzer.ElementKind.METHOD),
        plugin.ElementKind.METHOD);
    expect(converter.convertElementKind(analyzer.ElementKind.PARAMETER),
        plugin.ElementKind.PARAMETER);
    expect(converter.convertElementKind(analyzer.ElementKind.SETTER),
        plugin.ElementKind.SETTER);
    expect(
        converter.convertElementKind(analyzer.ElementKind.TOP_LEVEL_VARIABLE),
        plugin.ElementKind.TOP_LEVEL_VARIABLE);
    expect(converter.convertElementKind(analyzer.ElementKind.TYPE_PARAMETER),
        plugin.ElementKind.TYPE_PARAMETER);
  }

  test_convertErrorSeverity() {
    for (analyzer.ErrorSeverity severity in analyzer.ErrorSeverity.values) {
      if (severity != analyzer.ErrorSeverity.NONE) {
        expect(converter.convertErrorSeverity(severity), isNotNull,
            reason: severity.name);
      }
    }
  }

  test_convertErrorType() {
    for (analyzer.ErrorType type in analyzer.ErrorType.values) {
      expect(converter.convertErrorType(type), isNotNull, reason: type.name);
    }
  }

  test_fromElement_LABEL() async {
    analyzer.Source source = addSource(testFile, '''
main() {
myLabel:
  while (true) {
    break myLabel;
  }
}''');
    analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
    analyzer.LabelElement engineElement = findElementInUnit(unit, 'myLabel');
    // create notification Element
    plugin.Element element = converter.convertElement(engineElement);
    expect(element.kind, plugin.ElementKind.LABEL);
    expect(element.name, 'myLabel');
    {
      plugin.Location location = element.location;
      expect(location.file, testFile);
      expect(location.offset, 9);
      expect(location.length, 'myLabel'.length);
      expect(location.startLine, 2);
      expect(location.startColumn, 1);
    }
    expect(element.parameters, isNull);
    expect(element.returnType, isNull);
    expect(element.flags, 0);
  }
}
