// Copyright (c) 2014, 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:async';

import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../support/integration_tests.dart';

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

@reflectiveTest
class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
  Map<HighlightRegionType, Set<String>> highlights;

  void check(HighlightRegionType type, List<String> expected) {
    expect(highlights[type], equals(expected.toSet()));
    highlights.remove(type);
  }

  computeHighlights(String pathname, String text) async {
    writeFile(pathname, text);
    standardAnalysisSetup();
    sendAnalysisSetSubscriptions({
      AnalysisService.HIGHLIGHTS: [pathname]
    });
    // Map from highlight type to highlighted text
    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
      expect(params.file, equals(pathname));
      highlights = <HighlightRegionType, Set<String>>{};
      for (HighlightRegion region in params.regions) {
        int startIndex = region.offset;
        int endIndex = startIndex + region.length;
        String highlightedText = text.substring(startIndex, endIndex);
        HighlightRegionType type = region.type;
        if (!highlights.containsKey(type)) {
          highlights[type] = new Set<String>();
        }
        highlights[type].add(highlightedText);
      }
    });
    await analysisFinished;
  }

  @override
  Future startServer({
    int diagnosticPort,
    int servicesPort,
  }) {
    return server.start(
        diagnosticPort: diagnosticPort,
        servicesPort: servicesPort,
        useAnalysisHighlight2: true);
  }

  test_highlights() async {
    String pathname = sourcePath('test.dart');
    String text = r'''
import 'dart:async' as async;

/**
 * Doc comment
 */
class Class<TypeParameter> {
  Class() {
    field = {1.0: [].toList()};
  }

  Class.constructor() {
    dynamic local = true;
    field = {2: local};
  }

  Map field;
  static int staticField;

  method() {
    // End of line comment
    /* Block comment */
  }

  static staticMethod() {
  }

  get getter {
  }

  set setter(int parameter) {
    print(parameter);
  }
}

class Class2<TypeParameter> extends Class<TypeParameter> {
  @override
  method() {
  }
}

typedef functionType();

function(dynamicType) {
  print('string');
  unresolvedIdentifier = 42;
  return async.Future.wait([]);
}

int topLevelVariable;
''';
    await computeHighlights(pathname, text);
    // There should be 1 error due to the fact that unresolvedIdentifier is
    // unresolved.
    expect(currentAnalysisErrors[pathname], hasLength(1));
    void check(HighlightRegionType type, List<String> expected) {
      expect(highlights[type], equals(expected.toSet()));
      highlights.remove(type);
    }

    check(HighlightRegionType.ANNOTATION, ['@override']);
    check(HighlightRegionType.BUILT_IN,
        ['as', 'get', 'import', 'set', 'static', 'typedef']);
    check(
        HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
    check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
    check(HighlightRegionType.COMMENT_DOCUMENTATION,
        ['/**\n * Doc comment\n */']);
    check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
    check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
    check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
    check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
    check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
    check(HighlightRegionType.IMPORT_PREFIX, ['async']);
    check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
    check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
    check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
    check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']);
    check(HighlightRegionType.LITERAL_LIST, ['[]']);
    check(
        HighlightRegionType.LITERAL_MAP, ['{1.0: [].toList()}', '{2: local}']);
    check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
        ['topLevelVariable']);
    check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
    check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
    expect(highlights, isEmpty);
  }

  test_highlights_mixin() async {
    String pathname = sourcePath('test.dart');
    String text = r'''
mixin M on A implements B {}
class A {}
class B {}
''';
    await computeHighlights(pathname, text);
    expect(currentAnalysisErrors[pathname], hasLength(0));
    check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
    check(HighlightRegionType.KEYWORD, ['class']);
  }
}
