// 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 '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';

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

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

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

  Future<void> computeHighlights(String pathname, String text) async {
    writeFile(pathname, text);
    await standardAnalysisSetup();
    await analysisFinished;
    await 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 (var region in params.regions) {
        var startIndex = region.offset;
        var endIndex = startIndex + region.length;
        var highlightedText = text.substring(startIndex, endIndex);
        var type = region.type;
        highlights.putIfAbsent(type, () => {}).add(highlightedText);
      }
    });
    await analysisFinished;
  }

  @override
  Future<void> startServer({int? diagnosticPort, int? servicePort}) {
    return server.start(
      dartSdkPath: dartSdkPath,
      diagnosticPort: diagnosticPort,
      servicePort: servicePort,
      useAnalysisHighlight2: true,
    );
  }

  Future<void> test_highlights() async {
    var pathname = sourcePath('test.dart');
    var 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 = {3: 4};
  static int staticField = 0;

  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();
typedef genericTypeDef = double;

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

int topLevelVariable = 0;
''';
    await computeHighlights(pathname, text);
    // There should be 1 error due to the fact that unresolvedIdentifier is
    // unresolved.
    expect(currentAnalysisErrors[pathname], hasLength(1));

    check(HighlightRegionType.ANNOTATION, ['@override']);
    check(HighlightRegionType.BUILT_IN, [
      'as',
      'get',
      'import',
      'set',
      'static',
      'typedef',
    ]);
    check(HighlightRegionType.CLASS, [
      'Class',
      'Class2',
      'double',
      '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.TYPE_ALIAS, ['genericTypeDef']);
    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', '3', '4', '0', '42']);
    check(HighlightRegionType.LITERAL_LIST, ['[]']);
    check(HighlightRegionType.LITERAL_MAP, [
      '{1.0: [].toList()}',
      '{2: local}',
      '{3: 4}',
    ]);
    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);
  }

  Future<void> test_highlights_mixin() async {
    var pathname = sourcePath('test.dart');
    var 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']);
  }

  Future<void> test_highlights_tryCatch() async {
    var pathname = sourcePath('test.dart');
    var text = r'''
void f() {
  try {
  } on ArgumentError catch (error1, stackTrace1) {
  } on UnimplementedError catch (error2, stackTrace2) {
  } on IndexError catch (error2) {
  } catch (error3, stackTrace3) {
  }
}
''';
    await computeHighlights(pathname, text);

    check(HighlightRegionType.BUILT_IN, ['on']);
    check(HighlightRegionType.KEYWORD, ['void', 'try', 'catch']);
    check(HighlightRegionType.CLASS, [
      'ArgumentError',
      'UnimplementedError',
      'IndexError',
    ]);
    check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, [
      'error1',
      'stackTrace1',
      'error2',
      'stackTrace2',
      'error3',
      'stackTrace3',
    ]);
  }
}
