// 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.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/plugin/plugin_locator.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/utilities/extensions/file_system.dart';
import 'package:analyzer/utilities/package_config_file_builder.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_testing/utilities/utilities.dart';
import 'package:analyzer_utilities/testing/tree_string_sink.dart';
import 'package:collection/collection.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'analysis_server_base.dart';
import 'mocks.dart';
import 'services/completion/dart/text_expectations.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisDomainBlazeTest);
    defineReflectiveTests(AnalysisDomainPubTest);
    defineReflectiveTests(SetAnalysisRootsTest);
    defineReflectiveTests(SetSubscriptionsTest);
    defineReflectiveTests(UpdateTextExpectations);
  });
}

@reflectiveTest
class AnalysisDomainBlazeTest extends _AnalysisDomainTest {
  String get myPackageLibPath => '$myPackageRootPath/lib';

  String get myPackageRootPath => '$workspaceRootPath/dart/my';

  String get myPackageTestFilePath => '$myPackageLibPath/test.dart';

  @override
  void setUp() {
    super.setUp();
    newFile('$workspaceRootPath/${file_paths.blazeWorkspaceMarker}', '');
  }

  Future<void> test_fileSystem_changeFile_buildFile_legacy() async {
    // Make it a Blaze package.
    newBazelBuildFile(myPackageRootPath, r'''
# foo
''');

    newFile(myPackageTestFilePath, '''
void f(int? a) {}
''');

    await setRoots(included: [myPackageRootPath], excluded: []);
    await server.onAnalysisComplete;

    // No errors after initial analysis.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/dart/my/lib/test.dart
  errors: empty
''');

    // Change BUILD file, nothing interesting.
    newBazelBuildFile(myPackageRootPath, r'''
# bar
''');

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // BUILD file change caused rebuilding analysis contexts.
    assertNotificationsText(r'''
AnalysisFlush
  /home/dart/my/lib/test.dart
AnalysisErrors
  file: /home/dart/my/lib/test.dart
  errors: empty
''');
  }
}

@reflectiveTest
class AnalysisDomainPubTest extends _AnalysisDomainTest {
  Future<void> test_fileSystem_addFile_analysisOptions() async {
    deleteTestPackageAnalysisOptionsFile();

    _createFilesWithErrors([
      '$testPackageLibPath/a.dart',
      '$testPackageLibPath/b.dart',
    ]);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Both a.dart and b.dart are analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    // Write the options file that excludes b.dart
    newAnalysisOptionsYamlFile(testPackageRootPath, r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // Errors for all files were flushed, b.dart is not reported.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/a.dart
  /home/test/lib/b.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_analysisOptions_analysis() async {
    deleteTestPackageAnalysisOptionsFile();
    _createFilesWithErrors(['$testPackageLibPath/a.dart']);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Add 'analysis_options.yaml' that has an error.
    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  error:
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // Both files were analyzed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/a.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_androidManifestXml() async {
    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    newFile('$testPackageLibPath/a.dart', '');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    newFile('$testPackageRootPath/AndroidManifest.xml', '<manifest/>');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // No touch-screen.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_dart() async {
    // We have to create the folder, otherwise there is nothing to watch.
    newFolder(testPackageLibPath);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We don't have a.dart yet.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
''');

    _createFilesWithErrors(['$testPackageLibPath/a.dart']);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We created a.dart, so it should be analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_dart_dotFolder() async {
    var aPath = '$testPackageLibPath/.foo/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newFile(bPath, r'''
import '.foo/a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We don't have a.dart, so the import cannot be resolved.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    newFile(aPath, r'''
class A {}
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    // We added a.dart with `A`, so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_addFile_dart_excluded() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newAnalysisOptionsYamlFile(testPackageRootPath, r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(bPath, r'''
import 'a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We don't have a.dart, so the import cannot be resolved.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    newFile(aPath, r'''
class A {}
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    // We added a.dart with `A`, so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_addFile_fixDataFolderYaml() async {
    var path = '$testPackageLibPath/fix_data/foo.yaml';

    newFile('$testPackageLibPath/a.dart', '');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // No `fix_data.yaml` to analyze yet.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Create it, will be analyzed.
    newFile(path, '0: 1');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // And it has errors.
    // We don't recreate analysis contexts.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/fix_data/foo.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/fix_data/foo.yaml
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', '');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // No `fix_data.yaml` to analyze yet.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Create it, will be analyzed.
    newFile(path, '0: 1');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // And it has errors.
    // We don't recreate analysis contexts.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var aPath = '$aaaRootPath/lib/a.dart';

    newFile(aPath, '''
class A {}
''');

    newFile(testFilePath, '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');

    // Write `package_config.json`, recreate analysis contexts.
    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRootPath),
    );

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We rebuilt analysis contexts.
    // We have `A` in 'package:aaa/a.dart', so no errors.
    // Errors are not reported for packages.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/test.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_addFile_pubspec_analysis() async {
    var aPath = '$testPackageLibPath/a.dart';
    var pubspecPath = '$testPackageRootPath/pubspec.yaml';

    newFile(aPath, 'error');

    // Write an empty file to force a new analysis context.
    // We look for `pubspec.yaml` files only in analysis context roots.
    newAnalysisOptionsYamlFile(testPackageRootPath, '');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Add a non-Dart file that we know how to analyze.
    newFile(pubspecPath, '''
name: sample
dependencies: true
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We rebuilt analysis contexts.
    // All files were analyzed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/a.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_addFile_unrelated() async {
    var aPath = '$testPackageLibPath/a.dart';
    var unrelatedPath = '$testPackageRootPath/unrelated.txt';

    newFile(aPath, 'error');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Add an unrelated file, no analysis.
    newFile(unrelatedPath, 'anything');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // No analysis.
    assertNotificationsText(r'''
''');
  }

  Future<void> test_fileSystem_changeFile_analysisOptions() async {
    var optionsPath = '$testPackageRootPath/analysis_options.yaml';
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';
    var cPath = '$testPackageLibPath/c.dart';

    _createFilesWithErrors([aPath, bPath, cPath]);

    // Exclude 'b.dart' from analysis.
    newFile(optionsPath, r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Only 'a.dart' and 'c.dart' are analyzed, because 'b.dart' is excluded.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/c.dart
  errors: notEmpty
''');

    // Exclude 'c.dart' from analysis.
    newFile(optionsPath, r'''
analyzer:
  exclude:
    - lib/c.dart
''');

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // Analysis contexts were rebuilt.
    // Only 'a.dart' and 'b.dart' analyzed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/a.dart
  /home/test/lib/c.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_changeFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', '');

    // Has an error - no touch screen.
    newFile(path, '<manifest/>');

    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Update the file, so analyze it.
    newFile(path, '<manifest/>');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // An error was reported.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_changeFile_dart() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newFile(aPath, r'''
class A2 {}
''');

    newFile(bPath, r'''
import 'a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    // Update a.dart so that b.dart has no error.
    newFile(aPath, 'class A {}');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // The update of a.dart fixed the error in b.dart
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_changeFile_dart_dotFolder() async {
    var aPath = '$testPackageLibPath/.foo/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newFile(aPath, r'''
class B {}
''');

    newFile(bPath, r'''
import '.foo/a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    // We have `B`, not `A`, in a.dart, so has errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    newFile(aPath, r'''
class A {}
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    // We changed a.dart, to have `A`, so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_changeFile_dart_excluded() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newAnalysisOptionsYamlFile(testPackageRootPath, r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(aPath, r'''
class B {}
''');

    newFile(bPath, r'''
import 'a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    // We have `B`, not `A`, in a.dart, so has errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');

    newFile(aPath, r'''
class A {}
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We changed a.dart, to have `A`, so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_changeFile_fixDataFolderYaml() async {
    var path = '$testPackageLibPath/fix_data/foo.yaml';

    newFile('$testPackageLibPath/a.dart', '');

    // This file has an error.
    newFile(path, '0: 1');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // The file was analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data/foo.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Replace with the content that does not have errors.
    newFile(path, r'''
version: 1
transforms: []
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // No errors in `foo.yaml` anymore.
    // We don't recreate analysis contexts.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/fix_data/foo.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data/foo.yaml
  errors: empty
''');
  }

  Future<void> test_fileSystem_changeFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', '');

    // This file has an error.
    newFile(path, '0: 1');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // The file was analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Replace with the content that does not have errors.
    newFile(path, r'''
version: 1
transforms: []
''');
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // No errors in `fix_data.yaml` anymore.
    // We don't recreate analysis contexts.
    // TODO(scheglov): Why duplicate analysis?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: empty
''');
  }

  Future<void> test_fileSystem_changeFile_hasOverlay_removeOverlay() async {
    newFile(testFilePath, '');

    // Add an overlay without errors.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    await setRoots(included: [workspaceRootPath], excluded: []);

    // The test file (overlay) is analyzed, no errors.
    await _waitAnalysisComplete();
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');

    // Change the file, has errors.
    newFile(testFilePath, 'error');

    // But the overlay is still present, so the file is not analyzed.
    await _waitAnalysisComplete();
    assertNotificationsText(r'''
''');

    // Remove the overlay, now the file will be read.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: RemoveContentOverlay(),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    // The file has errors.
    await _waitAnalysisComplete();
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_changeFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var aPath = '$aaaRootPath/lib/a.dart';

    newFile(aPath, '''
class A {}
''');

    newFile(testFilePath, '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // The default `package_config.json` is without `package:aaa`.
    // We cannot resolve `package:aaa/a.dart`
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');

    // Write `package_config.json`, recreate analysis contexts.
    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRootPath),
    );

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    // Errors are not reported for packages.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/test.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');
  }

  Future<void> test_fileSystem_deleteFile_analysisOptions() async {
    var optionsPath = '$testPackageRootPath/analysis_options.yaml';
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([aPath, bPath]);

    // Exclude b.dart from analysis.
    newFile(optionsPath, r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Only a.dart is analyzed, because b.dart is excluded.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Delete the options file.
    deleteFile(optionsPath);

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // Errors for a.dart were flushed, a.dart and b.dart analyzed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/a.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_deleteFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', '');

    // Has an error - no touch screen.
    newFile(path, '<manifest/>');

    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // An error was reported.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Delete the file.
    deleteFile(path);
    await pumpEventQueue(times: 5000);

    // We received a flush notification.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/AndroidManifest.xml
''');
  }

  /// Tests that deleting and re-creating a file while an overlay is active
  /// keeps the diagnotics when the overlay is then removed, then removes them
  /// when the file is deleted.
  ///
  /// https://github.com/dart-lang/sdk/issues/53475
  Future<void> test_fileSystem_deleteFile_createFile_withOverlay_dart() async {
    var aPath = convertPath('$testPackageLibPath/a.dart');

    _createFilesWithErrors([aPath]);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Initial file has errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Set the overlay, with a different content.
    // We get another notification with errors.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        aPath: AddContentOverlay('error2'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Delete the file, we have the overlay, so no notifications.
    deleteFile(aPath);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
''');

    // Re-creating the file, we have the overlay, so no notifications.
    _createFilesWithErrors([aPath]);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
''');

    // Remove the overlay, the file has different content, so notification.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        aPath: RemoveContentOverlay(),
      }).toRequest('1', clientUriConverter: server.uriConverter),
    );
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Delete the file, errors are now gone.
    deleteFile(aPath);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/a.dart
''');
  }

  Future<void> test_fileSystem_deleteFile_dart() async {
    var aPath = '$testPackageLibPath/a.dart';

    _createFilesWithErrors([aPath]);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    deleteFile(aPath);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We deleted a.dart, its errors should be flushed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/a.dart
''');
  }

  Future<void> test_fileSystem_deleteFile_dart_excluded() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newAnalysisOptionsYamlFile(testPackageRootPath, r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(aPath, r'''
class A {}
''');

    newFile(bPath, r'''
import 'a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    // We have `A` in a.dart, so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: empty
''');

    deleteFile(aPath);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We deleted a.dart, so `A` cannot be resolved.
    // TODO(scheglov): Should we get flush for a.dart also?
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');
  }

  Future<void> test_fileSystem_deleteFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', '');

    // This file has an error.
    newFile(path, '0: 1');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // The file was analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');

    // Delete the file.
    deleteFile(path);
    await pumpEventQueue(times: 5000);

    // We received a flush notification.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/fix_data.yaml
''');
  }

  Future<void> test_fileSystem_deleteFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var aPath = '$aaaRootPath/lib/a.dart';

    newFile(aPath, '''
class A {}
''');

    // Write the empty file, without `package:aaa`.
    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRootPath),
    );

    newFile(testFilePath, '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');

    // Delete `package_config.json`, recreate analysis contexts.
    deleteFile('$testPackageRootPath/.dart_tool/package_config.json');

    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;

    // We cannot resolve 'package:aaa/a.dart', so errors.
    // Errors are not reported for packages.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/analysis_options.yaml
  /home/test/lib/test.dart
  /home/test/pubspec.yaml
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');
  }

  /// Tests that deleting a file does not clear diagnostics if there's still
  /// an active overlay for the file.
  ///
  /// https://github.com/dart-lang/sdk/issues/53475
  Future<void> test_fileSystem_deleteFile_withOverlay_dart() async {
    var aPath = convertPath('$testPackageLibPath/a.dart');

    _createFilesWithErrors([aPath]);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Initial file has errors.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Set overlay with different content, with errors.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        aPath: AddContentOverlay('error2'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Delete file, has the overlay, no notifications.
    deleteFile(aPath);
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
''');

    // After removing the overlay, errors are gone.
    // TODO(scheglov): why not flush?
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        aPath: RemoveContentOverlay(),
      }).toRequest('1', clientUriConverter: server.uriConverter),
    );
    await pumpEventQueue(times: 5000);
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');
  }

  Future<void> test_setPriorityFiles() async {
    var a = getFile('$workspaceRootPath/foo/lib/a.dart');
    var b = getFile('$workspaceRootPath/foo/lib/b.dart');
    var c = getFile('$workspaceRootPath/bar/lib/c.dart');
    var d = getFile('$workspaceRootPath/bar/lib/d.dart');

    a.writeAsStringSync('');
    b.writeAsStringSync('');
    c.writeAsStringSync('');
    d.writeAsStringSync('');

    await handleSuccessfulRequest(
      AnalysisSetPriorityFilesParams([
        a.path,
        c.path,
      ]).toRequest('0', clientUriConverter: server.uriConverter),
    );

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart and c.dart are priority files.
    // So, they are analyzed before b.dart and d.dart
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/foo/lib/a.dart
  errors: empty
AnalysisErrors
  file: /home/bar/lib/c.dart
  errors: empty
AnalysisErrors
  file: /home/foo/lib/b.dart
  errors: empty
AnalysisErrors
  file: /home/bar/lib/d.dart
  errors: empty
''');
  }

  Future<void> test_setPriorityFiles_notAbsolute() async {
    var response = await handleRequest(
      AnalysisSetPriorityFilesParams([
        'a.dart',
      ]).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_setPriorityFiles_withoutRoots() async {
    await handleSuccessfulRequest(
      AnalysisSetPriorityFilesParams([
        convertPath('$testPackageLibPath/a.dart'),
      ]).toRequest('0', clientUriConverter: server.uriConverter),
    );
  }

  Future<void> test_setRoots_excluded_notAbsolute() async {
    var response = await handleRequest(
      AnalysisSetAnalysisRootsParams(
        [workspaceRootPath],
        ['foo'],
        packageRoots: {},
      ).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_setRoots_excluded_notNormalized() async {
    var response = await handleRequest(
      AnalysisSetAnalysisRootsParams(
        [workspaceRootPath],
        [convertPath('/foo/../bar')],
        packageRoots: {},
      ).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_setRoots_included_notAbsolute() async {
    var response = await handleRequest(
      AnalysisSetAnalysisRootsParams(
        ['foo'],
        [],
        packageRoots: {},
      ).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_setRoots_included_notNormalized() async {
    var response = await handleRequest(
      AnalysisSetAnalysisRootsParams(
        [convertPath('/foo/../bar')],
        [],
        packageRoots: {},
      ).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_setRoots_includedFile() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([aPath, bPath]);

    await setRoots(included: [aPath], excluded: []);

    // Only a.dart is included, so b.dart is not analyzed.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_includedFile_setRoots() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([aPath, bPath]);

    // Include only single file.
    await setRoots(included: [aPath], excluded: []);
    await server.onAnalysisComplete;

    // So, only a.dart is analyzed, and b.dart is not.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');

    // Include the folder that contains both a.dart and b.dart
    await setRoots(included: [testPackageRootPath], excluded: []);
    await server.onAnalysisComplete;

    // So, both a.dart and b.dart are analyzed.
    assertNotificationsText(r'''
AnalysisFlush
  /home/test/lib/a.dart
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/b.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_includedFileFolder() async {
    var includedFile = '$testPackageLibPath/a.dart';
    var includedFolder = '$testPackageLibPath/foo';
    var includedFolderFile1 = '$includedFolder/1.dart';
    var includedFolderFile2 = '$includedFolder/2.dart';
    var notIncludedFile = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([
      includedFile,
      includedFolderFile1,
      includedFolderFile2,
      notIncludedFile,
    ]);

    await setRoots(included: [includedFile, includedFolder], excluded: []);
    await server.onAnalysisComplete;

    // We can combine a file, and a folder as included paths.
    // And the file that is not in there is not analyzed.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/foo/1.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/foo/2.dart
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_includedFolder_analysisOptions_exclude() async {
    var aPath = '$testPackageLibPath/a.dart';
    var bPath = '$testPackageLibPath/b.dart';

    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  exclude:
    - "**/b.dart"
''');

    _createFilesWithErrors([aPath, bPath]);

    await setRoots(included: [workspaceRootPath], excluded: []);

    // b.dart is excluded using the options file.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  @FailingTest(reason: 'Not implemented in ContextLocator')
  Future<void> test_setRoots_includedFolder_excludedFile() async {
    var aPath = '$testPackageLibPath/a.dart';
    var excluded_path = '$testPackageRootPath/excluded/b.dart';

    _createFilesWithErrors([aPath, excluded_path]);

    await setRoots(included: [workspaceRootPath], excluded: [excluded_path]);
    await server.onAnalysisComplete;

    fail('Not implemented');
  }

  Future<void> test_setRoots_includedFolder_excludedFolder() async {
    var aPath = '$testPackageLibPath/a.dart';
    var excluded_path = '$testPackageRootPath/excluded/b.dart';

    _createFilesWithErrors([aPath, excluded_path]);

    await setRoots(
      included: [workspaceRootPath],
      excluded: ['$testPackageRootPath/excluded'],
    );
    await server.onAnalysisComplete;

    // a.dart is analyzed, but b.dart is in the excluded folder.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_includedFolder_notExisting() async {
    var existingFolder_path = '$testPackageLibPath/exiting';
    var notExistingFolder_path = '$testPackageLibPath/notExisting';
    var existingFile_path = '$existingFolder_path/1.dart';

    _createFilesWithErrors([existingFile_path]);

    await setRoots(
      included: [existingFolder_path, notExistingFolder_path],
      excluded: [],
    );
    await server.onAnalysisComplete;

    // The not existing root does not prevent analysis of the existing one.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/exiting/1.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_notDartFile_analysisOptions_excluded() async {
    deleteTestPackageAnalysisOptionsFile();
    var aPath = '$testPackageLibPath/a.dart';
    var optionsPath = '$testPackageRootPath/analysis_options.yaml';

    newFile(aPath, 'error');

    // 'analysis_options.yaml' that has an error and excludes itself.
    newFile(optionsPath, '''
analyzer:
  exclude:
    - analysis_options.yaml
  error:
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_notDartFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', '');

    newAnalysisOptionsYamlFile(testPackageRootPath, '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    newFile(path, '<manifest/>');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    // No touch-screen.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/AndroidManifest.xml
  errors: notEmpty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: empty
''');
  }

  Future<void> test_setRoots_notDartFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    // `lib/fix_data.yaml` will be analyzed.
    newFile(path, '0: 1');

    await setRoots(included: [workspaceRootPath], excluded: []);

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_notDartFile_fixDataYaml_empty() async {
    var path = '$testPackageLibPath/fix_data.yaml';
    newFile(path, '');

    await setRoots(included: [workspaceRootPath], excluded: []);

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: empty
''');
  }

  Future<void> test_setRoots_notDartFile_fixDataYaml_onlyComments() async {
    var path = '$testPackageLibPath/fix_data.yaml';
    newFile(path, '# one\n#two');

    await setRoots(included: [workspaceRootPath], excluded: []);

    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/fix_data.yaml
  errors: empty
''');
  }

  Future<void> test_setRoots_notDartFile_pubspec_excluded() async {
    deleteTestPackageAnalysisOptionsFile();
    var aPath = '$testPackageLibPath/a.dart';
    var optionsPath = '$testPackageRootPath/analysis_options.yaml';

    newFile(aPath, 'error');

    writeTestPackagePubspecYamlFile('''
name:
  - error
''');

    // 'analysis_options.yaml' that excludes pubspec.yaml.
    newFile(optionsPath, '''
analyzer:
  exclude:
    - pubspec.yaml
''');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // No pubspec.yaml
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/a.dart
  errors: notEmpty
''');
  }

  Future<void> test_setRoots_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var aPath = '$aaaRootPath/lib/a.dart';

    newFile(aPath, '''
class A {}
''');

    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRootPath),
    );

    newFile(testFilePath, '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    // create project and wait for analysis
    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    // Errors are not reported for packages.
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');
  }

  Future<void> test_updateContent_addOverlay() async {
    newFile(testFilePath, 'error');

    await setRoots(included: [workspaceRootPath], excluded: []);

    // The file in the file system has errors.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');

    // Add an overlay without errors.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    // A new errors notification was received, no errors.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');
  }

  Future<void> test_updateContent_changeOverlay() async {
    newFile(testFilePath, '');

    // Add the content with an error.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay('var v = 0'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    await setRoots(included: [workspaceRootPath], excluded: []);

    // The overlay has an error.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/pubspec.yaml
  errors: empty
AnalysisErrors
  file: /home/test/analysis_options.yaml
  errors: empty
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: notEmpty
''');

    // Add the missing `;`.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([SourceEdit(9, 0, ';')]),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    // A new errors notification was received, no errors.
    await server.onAnalysisComplete;
    assertNotificationsText(r'''
AnalysisErrors
  file: /home/test/lib/test.dart
  errors: empty
''');
  }

  Future<void> test_updateContent_notAbsolute() async {
    var response = await handleRequest(
      AnalysisUpdateContentParams({
        'a.dart': AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    expect(response, isResponseFailure('0'));
  }

  Future<void> test_updateContent_outOfRange_beyondEnd() {
    return _updateContent_outOfRange('012', SourceEdit(0, 5, 'foo'));
  }

  Future<void> test_updateContent_outOfRange_negativeLength() {
    return _updateContent_outOfRange('', SourceEdit(3, -1, 'foo'));
  }

  Future<void> test_updateContent_outOfRange_negativeOffset() {
    return _updateContent_outOfRange('', SourceEdit(-1, 3, 'foo'));
  }

  Future<void> _updateContent_outOfRange(
    String initialContent,
    SourceEdit edit,
  ) async {
    newFile(testFilePath, initialContent);

    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay(initialContent),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    var response = await handleRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([edit]),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );

    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE),
    );
  }

  /// Pump the event queue, so that watch events are processed.
  /// Wait for analysis to complete.
  /// Repeat a few times, eventually there will be no work to do.
  Future<void> _waitAnalysisComplete() async {
    for (var i = 0; i < 128; i++) {
      await pumpEventQueue(times: 5000);
      await server.onAnalysisComplete;
    }
  }
}

@reflectiveTest
class SetAnalysisRootsTest extends PubPackageAnalysisServerTest {
  /// Verifies the set of context roots created by the server and which were
  /// provided to each plugin.
  void expectPluginMapping(Map<String, List<String>> expected) {
    var pluginMapping = pluginManager.contextRootPlugins.map(
      (root, plugins) => MapEntry(
        pathContext.basename(root.root.path),
        plugins.map(
          (pluginPath) => pathContext.basename(
            pathContext.dirname(pathContext.dirname(pluginPath)),
          ),
        ),
      ),
    );

    // Additionally, add any context roots from the server that were not
    // provided to plugins so the tests can also explicitly verify roots were
    // created that didn't show up in the plugins list.
    for (var serverContext in server.contextManager.analysisContexts) {
      var name = pathContext.basename(serverContext.contextRoot.root.path);
      pluginMapping.putIfAbsent(name, () => []);
    }

    expect(pluginMapping, expected);
  }

  @override
  void setUp() {
    super.setUp();

    // These tests don't use the "test" package folder but have their own named
    // package folders. Delete the "test" folder so it doesn't show up as a
    // context root (else it would need listing in each test expectation).
    deleteFolder(testPackageRootPath);
  }

  /// Tests a package with a nested folder that has an additional
  /// `analysis_options.yaml` that does not enable the plugin. An additional
  /// context should be created for the non-plugin folder and it should be
  /// excluded from the parents plugin root.
  Future<void>
  test_sentToPlugins_inNestedPackages_withNestedAnalysisOptions_enabledPlugin_disabledPlugin() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));

    // package1 has plugin2 enabled.
    _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1],
    );

    // nestedFolder1 has no plugins enabled.
    newAnalysisOptionsYamlFile(
      join(workspaceRootPath, 'package1', 'nestedFolder1'),
      analysisOptionsContent(experiments: experiments),
    );

    // Write the single package config at the root that can resolve both
    // plugins.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()..add(name: 'plugin1', rootPath: plugin1.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      'nestedFolder1': [],
    });
  }

  /// Tests a package with a nested folder that has an additional
  /// `analysis_options.yaml` that enables a different plugin. An additional
  /// root should be created.
  Future<void>
  test_sentToPlugins_inNestedPackages_withNestedAnalysisOptions_enabledPlugin_enabledDifferentPlugin() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));
    var plugin2 = (name: 'plugin2', path: _createPlugin('plugin2'));

    // package1 has plugin2 enabled.
    _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1],
    );

    // nestedFolder1 has plugin2 enabled.
    newAnalysisOptionsYamlFile(
      join(workspaceRootPath, 'package1', 'nestedFolder1'),
      analysisOptionsContent(
        experiments: experiments,
        legacyPlugins: [plugin2.name],
      ),
    );

    // Write the single package config at the root that can resolve both
    // plugins.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()
        ..add(name: 'plugin1', rootPath: plugin1.path)
        ..add(name: 'plugin2', rootPath: plugin2.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      'nestedFolder1': ['plugin2'],
    });
  }

  /// Tests a package with a nested folder that has an additional
  /// `analysis_options.yaml` that enables the same plugin explicitly. No
  /// additional context needs to be created.
  Future<void>
  test_sentToPlugins_inNestedPackages_withNestedAnalysisOptions_enabledPlugin_enabledPluginExplicit() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));

    // package1 has plugin2 enabled.
    _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1],
    );

    // nestedFolder1 also has plugin1 enabled.
    newAnalysisOptionsYamlFile(
      join(workspaceRootPath, 'package1', 'nestedFolder1'),
      analysisOptionsContent(
        experiments: experiments,
        legacyPlugins: [plugin1.name],
      ),
    );

    // Write the single package config at the root that can resolve both
    // plugins.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()..add(name: 'plugin1', rootPath: plugin1.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      // nestedFolder1 is included as part of package1.
    });
  }

  /// Tests a package with a nested folder that has an additional
  /// `analysis_options.yaml` that enables the same plugin by including the
  /// parents `analysis_options.yaml`. No additional context needs to be
  /// created.
  Future<void>
  test_sentToPlugins_inNestedPackages_withNestedAnalysisOptions_enabledPlugin_enabledPluginInclude() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));

    // package1 has plugin2 enabled.
    _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1],
    );

    // nestedFolder1 also has plugin1 enabled because it includes the parent
    // `analysis_options.yaml`.
    newAnalysisOptionsYamlFile(
      join(workspaceRootPath, 'package1', 'nestedFolder1'),
      analysisOptionsContent(includes: ['../analysis_options.yaml']),
    );

    // Write the single package config at the root that can resolve both
    // plugins.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()..add(name: 'plugin1', rootPath: plugin1.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      // nestedFolder1 is included as part of package1.
    });
  }

  /// Test that the correct context roots are passed to plugins when they are
  /// enabled only for projects nested within the workspace (which do not have
  /// their own package configs but use the one from the root).
  ///
  /// In this example, we have three nested projects that use a mix of plugins:
  ///
  /// - root/ (no plugins enabled)
  ///   - package1/ (plugin1, (plugin2 - disabled due to limit))
  ///   - package2/ (plugin2, (plugin1 - disabled due to limit))
  ///   - package3/ (plugin1)
  Future<void>
  test_sentToPlugins_inNestedPackages_withoutPackageConfigs() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));
    var plugin2 = (name: 'plugin2', path: _createPlugin('plugin2'));

    // Only the first plugin for each will be enabled due to the 1-plugin-limit.
    _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1, plugin2],
    );
    _createTestPackage(
      'package2',
      withPackageConfig: false,
      plugins: [plugin2, plugin1],
    );
    _createTestPackage(
      'package3',
      withPackageConfig: false,
      plugins: [plugin1],
    );

    // Write the single package config at the root that can resolve both
    // plugins.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()
        ..add(name: 'plugin1', rootPath: plugin1.path)
        ..add(name: 'plugin2', rootPath: plugin2.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      'package2': ['plugin2'],
      'package3': ['plugin1'],
    });
  }

  /// Test that the correct context roots are passed to plugins when they are
  /// enabled only for projects nested within the workspace (which have their
  /// own package configs).
  ///
  /// In this example, we have three nested projects that use a mix of plugins:
  ///
  /// - root/ (no plugins enabled)
  ///   - package1/ (plugin1, (plugin2 - disabled due to limit))
  ///   - package2/ (plugin2, (plugin1 - disabled due to limit))
  ///   - package3/ (plugin1)
  Future<void> test_sentToPlugins_inNestedPackages_withPackageConfigs() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));
    var plugin2 = (name: 'plugin2', path: _createPlugin('plugin2'));

    // Only the first plugin for each will be enabled due to the 1-plugin-limit.
    _createTestPackage('package1', plugins: [plugin1, plugin2]);
    _createTestPackage('package2', plugins: [plugin2, plugin1]);
    _createTestPackage('package3', plugins: [plugin1]);

    // Ensure the root directory can resolve both plugin packages even though
    // we don't enabled them for the root. This will catch if we incorrectly try
    // to enable them because we read a child analysis_options.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()
        ..add(name: 'plugin1', rootPath: plugin1.path)
        ..add(name: 'plugin2', rootPath: plugin2.path),
    );

    // Set the analysis roots to the folder ('/home') that contains both
    // packages but not the plugins (which are in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
      'package2': ['plugin2'],
      'package3': ['plugin1'],
    });
  }

  /// Test that the correct context roots are passed to plugins when they are
  /// enabled for projects that contain subfolders that do not contain analysis
  /// options and so the existing plugins apply.
  ///
  /// In this example, a project has plugins and it has subfolders that inherit
  /// those options (and thus do not produce a new root).
  ///
  /// - root/ (no plugins enabled)
  ///   - package1/ (plugin1)
  ///   - package1/lib/ (no explicit options, plugin1 implied)
  Future<void> test_sentToPlugins_inNestedPackages_withSubFolders() async {
    var plugin1 = (name: 'plugin1', path: _createPlugin('plugin1'));

    // Only the first plugin for each will be enabled due to the 1-plugin-limit.
    var package1Path = _createTestPackage(
      'package1',
      withPackageConfig: false,
      plugins: [plugin1],
    );
    newFolder(join(package1Path, 'lib'));

    // Write the single package config at the root that can resolve the plugin.
    newPackageConfigJsonFileFromBuilder(
      workspaceRootPath,
      PackageConfigFileBuilder()..add(name: 'plugin1', rootPath: plugin1.path),
    );

    // Set the analysis roots to the folder ('/home') that contains the
    // package but not the plugin (which is in '/plugins').
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();

    expectPluginMapping({
      'home': [],
      'package1': ['plugin1'],
    });
  }

  /// Creates a plugin package named [name] and returns the path to the root
  /// of the package.
  String _createPlugin(String name) {
    var pluginDirectory = convertPath(join('/plugins', name));
    newPubspecYamlFile(pluginDirectory, 'name: $name');
    newFile(convertPath(join(pluginDirectory, 'lib', '$name.dart')), '');
    newFolder(
      join(
        pluginDirectory,
        PluginLocator.toolsFolderName,
        PluginLocator.defaultPluginFolderName,
        '$name.dart',
      ),
    );
    return pluginDirectory;
  }

  /// Creates a package in the test workspace named [name] that uses [plugins].
  String _createTestPackage(
    String name, {
    bool withPackageConfig = true,
    List<({String name, String path})> plugins = const [],
  }) {
    var packagePath = join(workspaceRootPath, name);

    newPubspecYamlFile(packagePath, 'name: $name');

    newAnalysisOptionsYamlFile(
      packagePath,
      analysisOptionsContent(
        experiments: experiments,
        legacyPlugins: plugins.map((plugin) => plugin.name).toList(),
      ),
    );

    if (withPackageConfig) {
      var packageConfig = PackageConfigFileBuilder()
        ..add(name: name, rootPath: packagePath);
      for (var plugin in plugins) {
        packageConfig.add(name: plugin.name, rootPath: plugin.path);
      }
      newPackageConfigJsonFileFromBuilder(packagePath, packageConfig);
    }

    return packagePath;
  }
}

@reflectiveTest
class SetSubscriptionsTest extends PubPackageAnalysisServerTest {
  Map<File, List<HighlightRegion>> filesHighlights = {};

  final Completer<void> _resultsAvailable = Completer();

  @override
  void processNotification(Notification notification) {
    super.processNotification(notification);
    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
      var params = AnalysisHighlightsParams.fromNotification(
        notification,
        clientUriConverter: server.uriConverter,
      );
      filesHighlights[getFile(params.file)] = params.regions;
      _resultsAvailable.complete();
    }
  }

  @override
  Future<void> setUp() async {
    super.setUp();
    await setRoots(included: [workspaceRootPath], excluded: []);
  }

  Future<void> test_afterAnalysis() async {
    addTestFile('int V = 42;');
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNull);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[testFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_noSuchFile() async {
    var file = getFile('/no-such-file.dart');
    addTestFile('// no matter');
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNull);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[file], isEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_external() async {
    var pkgFile = newFile('/packages/pkgA/lib/libA.dart', '''
library lib_a;
class A {}
''');
    writePackageConfig(
      convertPath('/project'),
      config: (PackageConfigFileBuilder()
        ..add(name: 'pkgA', rootPath: convertPath('/packages/pkgA'))),
    );
    //
    addTestFile('''
import 'package:pkgA/libA.dart';
void f() {
  new A();
}
''');
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFile], isNull);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_inRoot() async {
    var pkgA = convertPath('/pkgA');
    var pkgB = convertPath('/pkgA');
    var pkgFileA = newFile('$pkgA/lib/libA.dart', '''
library lib_a;
class A {}
''');
    newFile('$pkgA/lib/libB.dart', '''
import 'package:pkgA/libA.dart';
void f() {
  new A();
}
''');
    // add 'pkgA' and 'pkgB' as projects
    await setRoots(included: [pkgA, pkgB], excluded: []);
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFileA], isNull);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFileA);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFileA], isNotEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_notUsed() async {
    var pkgFile = newFile('/packages/pkgA/lib/libA.dart', '''
library lib_a;
class A {}
''');
    writePackageConfig(
      convertPath('/project'),
      config: (PackageConfigFileBuilder()
        ..add(name: 'pkgA', rootPath: convertPath('/packages/pkgA'))),
    );
    //
    addTestFile('// no "pkgA" reference');
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFile], isNull);
    // make it a priority file, so make analyzable
    server.setPriorityFiles('0', [pkgFile.path]);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_sdkFile() async {
    var file = getFile('/sdk/lib/core/core.dart');
    addTestFile('// no matter');
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[file], isNull);
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[file], isNotEmpty);
  }

  Future<void> test_beforeAnalysis() async {
    addTestFile('int V = 42;');
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    // wait for analysis
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNotEmpty);
  }

  Future<void> test_sentToPlugins() async {
    addTestFile('int V = 42;');
    // subscribe
    await addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    // wait for analysis
    await waitForTasksFinished();
    var params = pluginManager.analysisSetSubscriptionsParams!;
    var subscriptions = params.subscriptions;
    expect(subscriptions, hasLength(1));
    var files = subscriptions[plugin.AnalysisService.HIGHLIGHTS];
    expect(files, [testFile.path]);
  }
}

class _AnalysisDomainTest extends PubPackageAnalysisServerTest {
  final configuration = _NotificationPrinterConfiguration();
  final List<(String, Object)> notifications = [];

  void assertNotificationsText(String expected) {
    var buffer = StringBuffer();
    var sink = TreeStringSink(sink: buffer, indent: '');
    _NotificationPrinter(
      configuration: configuration,
      resourceProvider: resourceProvider,
      sink: sink,
    ).writeNotifications(notifications);
    notifications.clear();

    var actual = buffer.toString();
    if (actual != expected) {
      print('-------- Actual --------');
      print('$actual------------------------');
      TextExpectationsCollector.add(actual);
    }
    expect(actual, expected);
  }

  @override
  void processNotification(Notification notification) {
    if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
      var decoded = AnalysisFlushResultsParams.fromNotification(
        notification,
        clientUriConverter: server.uriConverter,
      );
      notifications.add((notification.event, decoded));
    }
    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
      var decoded = AnalysisErrorsParams.fromNotification(
        notification,
        clientUriConverter: server.uriConverter,
      );
      notifications.add((notification.event, decoded));
    }
  }

  /// Create files with a content that has a compile time error.
  void _createFilesWithErrors(List<String> paths) {
    for (var path in paths) {
      newFile(path, 'error');
    }
  }
}

class _NotificationPrinter {
  final _NotificationPrinterConfiguration configuration;
  final ResourceProvider resourceProvider;
  final TreeStringSink sink;

  _NotificationPrinter({
    required this.configuration,
    required this.resourceProvider,
    required this.sink,
  });

  void writeNotifications(List<(String, Object)> notifications) {
    for (var entry in notifications) {
      _writeNotification(entry.$1, entry.$2);
    }
  }

  void _writelnFile(String path, {String? name}) {
    sink.writeIndentedLine(() {
      if (name != null) {
        sink.write('$name: ');
      }
      var file = resourceProvider.getFile(path);
      sink.write(file.posixPath);
    });
  }

  void _writeNotification(String event, Object notification) {
    switch (notification) {
      case AnalysisFlushResultsParams():
        var files = notification.files.sorted();
        sink.writeElements('AnalysisFlush', files, _writelnFile);
      case AnalysisErrorsParams():
        sink.writelnWithIndent('AnalysisErrors');
        sink.withIndent(() {
          _writelnFile(name: 'file', notification.file);
          if (configuration.withAnalysisErrorDetails) {
            throw UnimplementedError();
          } else if (notification.errors.isNotEmpty) {
            sink.writelnWithIndent('errors: notEmpty');
          } else {
            sink.writelnWithIndent('errors: empty');
          }
        });
      default:
        throw UnimplementedError('${notification.runtimeType}');
    }
  }
}

class _NotificationPrinterConfiguration {
  bool withAnalysisErrorDetails = false;
}
