// 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 'dart:io' as io;

import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer_plugin/channel/channel.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart'
    hide ContextRoot;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart' as watcher;

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(BuiltInPluginInfoTest);
    defineReflectiveTests(DiscoveredPluginInfoTest);
    defineReflectiveTests(PluginManagerTest);
    defineReflectiveTests(PluginManagerFromDiskTest);
    defineReflectiveTests(PluginSessionTest);
    defineReflectiveTests(PluginSessionFromDiskTest);
  });
}

@reflectiveTest
class BuiltInPluginInfoTest with ResourceProviderMixin, _ContextRoot {
  late TestNotificationManager notificationManager;
  late BuiltInPluginInfo plugin;

  void setUp() {
    notificationManager = TestNotificationManager();
    plugin = BuiltInPluginInfo((_) {}, 'test plugin', notificationManager,
        InstrumentationService.NULL_SERVICE);
  }

  void test_addContextRoot() {
    var contextRoot1 = _newContextRoot('/pkg1');
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, [contextRoot1]);
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, [contextRoot1]);
  }

  void test_creation() {
    expect(plugin.pluginId, 'test plugin');
    expect(plugin.notificationManager, notificationManager);
    expect(plugin.contextRoots, isEmpty);
    expect(plugin.currentSession, isNull);
  }

  void test_removeContextRoot() {
    var contextRoot1 = _newContextRoot('/pkg1');
    var contextRoot2 = _newContextRoot('/pkg2');
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, unorderedEquals([contextRoot1]));
    plugin.addContextRoot(contextRoot2);
    expect(plugin.contextRoots, unorderedEquals([contextRoot1, contextRoot2]));
    plugin.removeContextRoot(contextRoot1);
    expect(plugin.contextRoots, unorderedEquals([contextRoot2]));
    plugin.removeContextRoot(contextRoot2);
    expect(plugin.contextRoots, isEmpty);
  }

  @failingTest
  Future<void> test_start_notRunning() {
    fail('Not tested');
  }

  Future<void> test_start_running() async {
    plugin.currentSession = PluginSession(plugin);
    try {
      await plugin.start('', '');
      fail('Expected a StateError');
    } on StateError {
      // Expected.
    }
  }

  void test_stop_notRunning() {
    expect(() => plugin.stop(), throwsStateError);
  }

  Future<void> test_stop_running() async {
    var session = PluginSession(plugin);
    var channel = TestServerCommunicationChannel(session);
    plugin.currentSession = session;
    await plugin.stop();
    expect(plugin.currentSession, isNull);
    expect(channel.sentRequests, hasLength(1));
    expect(channel.sentRequests[0].method, 'plugin.shutdown');
  }
}

@reflectiveTest
class DiscoveredPluginInfoTest with ResourceProviderMixin, _ContextRoot {
  late TestNotificationManager notificationManager;
  String pluginPath = '/pluginDir';
  String executionPath = '/pluginDir/bin/plugin.dart';
  String packagesPath = '/pluginDir/.packages';
  late DiscoveredPluginInfo plugin;

  void setUp() {
    notificationManager = TestNotificationManager();
    plugin = DiscoveredPluginInfo(pluginPath, executionPath, packagesPath,
        notificationManager, InstrumentationService.NULL_SERVICE);
  }

  void test_addContextRoot() {
    var contextRoot1 = _newContextRoot('/pkg1');
    var optionsFile = getFile('/pkg1/analysis_options.yaml');
    contextRoot1.optionsFile = optionsFile;
    var session = PluginSession(plugin);
    var channel = TestServerCommunicationChannel(session);
    plugin.currentSession = session;
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, [contextRoot1]);
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, [contextRoot1]);
    var sentRequests = channel.sentRequests;
    expect(sentRequests, hasLength(1));
    var roots = sentRequests[0].params['roots'] as List<Map>;
    expect(roots[0]['optionsFile'], optionsFile.path);
  }

  void test_creation() {
    expect(plugin.path, pluginPath);
    expect(plugin.executionPath, executionPath);
    expect(plugin.notificationManager, notificationManager);
    expect(plugin.contextRoots, isEmpty);
    expect(plugin.currentSession, isNull);
  }

  void test_removeContextRoot() {
    var contextRoot1 = _newContextRoot('/pkg1');
    var contextRoot2 = _newContextRoot('/pkg2');
    plugin.addContextRoot(contextRoot1);
    expect(plugin.contextRoots, unorderedEquals([contextRoot1]));
    plugin.addContextRoot(contextRoot2);
    expect(plugin.contextRoots, unorderedEquals([contextRoot1, contextRoot2]));
    plugin.removeContextRoot(contextRoot1);
    expect(plugin.contextRoots, unorderedEquals([contextRoot2]));
    plugin.removeContextRoot(contextRoot2);
    expect(plugin.contextRoots, isEmpty);
  }

  @failingTest
  Future<void> test_start_notRunning() {
    fail('Not tested');
  }

  Future<void> test_start_running() async {
    plugin.currentSession = PluginSession(plugin);
    try {
      await plugin.start('', '');
      fail('Expected a StateError');
    } on StateError {
      // Expected.
    }
  }

  void test_stop_notRunning() {
    expect(() => plugin.stop(), throwsStateError);
  }

  Future<void> test_stop_running() async {
    var session = PluginSession(plugin);
    var channel = TestServerCommunicationChannel(session);
    plugin.currentSession = session;
    await plugin.stop();
    expect(plugin.currentSession, isNull);
    expect(channel.sentRequests, hasLength(1));
    expect(channel.sentRequests[0].method, 'plugin.shutdown');
  }
}

@reflectiveTest
class PluginManagerFromDiskTest extends PluginTestSupport {
  String byteStorePath = '/byteStore';
  late PluginManager manager;

  @override
  void setUp() {
    super.setUp();
    manager = PluginManager(resourceProvider, byteStorePath, '',
        notificationManager, InstrumentationService.NULL_SERVICE);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_addPluginToContextRoot() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(test: (String pluginPath) async {
      var contextRoot = _newContextRoot(pkgPath);
      await manager.addPluginToContextRoot(contextRoot, pluginPath);
      await manager.stopAll();
    });
    pkg1Dir.deleteSync(recursive: true);
  }

  @failingTest
  Future<void> test_addPluginToContextRoot_pubspec() async {
    // We can't successfully run pub until after the analyzer_plugin package has
    // been published.
    fail('Cannot run pub');
//    io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
//    String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
//    await withPubspecPlugin(test: (String pluginPath) async {
//      ContextRoot contextRoot = _newContextRoot(pkgPath);
//      await manager.addPluginToContextRoot(contextRoot, pluginPath);
//      String packagesPath =
//          resourceProvider.pathContext.join(pluginPath, '.packages');
//      File packagesFile = resourceProvider.getFile(packagesPath);
//      bool exists = packagesFile.exists;
//      await manager.stopAll();
//      expect(exists, isTrue, reason: '.packages file was not created');
//    });
//    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_broadcastRequest_many() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        test: (String plugin1Path) async {
          await withPlugin(
              pluginName: 'plugin2',
              test: (String plugin2Path) async {
                var contextRoot = _newContextRoot(pkgPath);
                await manager.addPluginToContextRoot(contextRoot, plugin1Path);
                await manager.addPluginToContextRoot(contextRoot, plugin2Path);

                var responses = manager.broadcastRequest(
                    CompletionGetSuggestionsParams('/pkg1/lib/pkg1.dart', 100),
                    contextRoot: contextRoot);
                expect(responses, hasLength(2));

                await manager.stopAll();
              });
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_broadcastRequest_many_noContextRoot() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        test: (String plugin1Path) async {
          await withPlugin(
              pluginName: 'plugin2',
              test: (String plugin2Path) async {
                var contextRoot = _newContextRoot(pkgPath);
                await manager.addPluginToContextRoot(contextRoot, plugin1Path);
                await manager.addPluginToContextRoot(contextRoot, plugin2Path);

                var responses = manager.broadcastRequest(
                    CompletionGetSuggestionsParams('/pkg1/lib/pkg1.dart', 100));
                expect(responses, hasLength(2));

                await manager.stopAll();
              });
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_broadcastRequest_noCurrentSession() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        content: '(invalid content here)',
        test: (String plugin1Path) async {
          var contextRoot = _newContextRoot(pkgPath);
          await manager.addPluginToContextRoot(contextRoot, plugin1Path);

          var responses = manager.broadcastRequest(
              CompletionGetSuggestionsParams('/pkg1/lib/pkg1.dart', 100),
              contextRoot: contextRoot);
          expect(responses, hasLength(0));

          await manager.stopAll();
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_broadcastWatchEvent() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        test: (String plugin1Path) async {
          var contextRoot = _newContextRoot(pkgPath);
          await manager.addPluginToContextRoot(contextRoot, plugin1Path);
          var plugins = manager.pluginsForContextRoot(contextRoot);
          expect(plugins, hasLength(1));
          var watchEvent = watcher.WatchEvent(
              watcher.ChangeType.MODIFY, path.join(pkgPath, 'lib', 'lib.dart'));
          var responses = await manager.broadcastWatchEvent(watchEvent);
          expect(responses, hasLength(1));
          var response = await responses[0];
          expect(response, isNotNull);
          expect(response.error, isNull);
          await manager.stopAll();
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_pluginsForContextRoot_multiple() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        test: (String plugin1Path) async {
          await withPlugin(
              pluginName: 'plugin2',
              test: (String plugin2Path) async {
                var contextRoot = _newContextRoot(pkgPath);
                await manager.addPluginToContextRoot(contextRoot, plugin1Path);
                await manager.addPluginToContextRoot(contextRoot, plugin2Path);

                var plugins = manager.pluginsForContextRoot(contextRoot);
                expect(plugins, hasLength(2));
                var paths = plugins
                    .map((PluginInfo plugin) => plugin.pluginId)
                    .toList();
                expect(paths, unorderedEquals([plugin1Path, plugin2Path]));

                await manager.stopAll();
              });
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_pluginsForContextRoot_one() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(test: (String pluginPath) async {
      var contextRoot = _newContextRoot(pkgPath);
      await manager.addPluginToContextRoot(contextRoot, pluginPath);

      var plugins = manager.pluginsForContextRoot(contextRoot);
      expect(plugins, hasLength(1));
      expect(plugins[0].pluginId, pluginPath);

      await manager.stopAll();
    });
    pkg1Dir.deleteSync(recursive: true);
  }

  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_removedContextRoot() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkgPath = pkg1Dir.resolveSymbolicLinksSync();
    await withPlugin(test: (String pluginPath) async {
      var contextRoot = _newContextRoot(pkgPath);
      await manager.addPluginToContextRoot(contextRoot, pluginPath);

      manager.removedContextRoot(contextRoot);

      await manager.stopAll();
    });
    pkg1Dir.deleteSync(recursive: true);
  }

  @TestTimeout(Timeout.factor(4))
  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_restartPlugins() async {
    var pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
    var pkg1Path = pkg1Dir.resolveSymbolicLinksSync();
    var pkg2Dir = io.Directory.systemTemp.createTempSync('pkg2');
    var pkg2Path = pkg2Dir.resolveSymbolicLinksSync();
    await withPlugin(
        pluginName: 'plugin1',
        test: (String plugin1Path) async {
          await withPlugin(
              pluginName: 'plugin2',
              test: (String plugin2Path) async {
                var contextRoot1 = _newContextRoot(pkg1Path);
                var contextRoot2 = _newContextRoot(pkg2Path);
                await manager.addPluginToContextRoot(contextRoot1, plugin1Path);
                await manager.addPluginToContextRoot(contextRoot1, plugin2Path);
                await manager.addPluginToContextRoot(contextRoot2, plugin1Path);

                await manager.restartPlugins();
                var plugins = manager.plugins;
                expect(plugins, hasLength(2));
                expect(plugins[0].currentSession, isNotNull);
                expect(plugins[1].currentSession, isNotNull);
                if (plugins[0].pluginId.contains('plugin1')) {
                  expect(plugins[0].contextRoots,
                      unorderedEquals([contextRoot1, contextRoot2]));
                  expect(
                      plugins[1].contextRoots, unorderedEquals([contextRoot1]));
                } else {
                  expect(
                      plugins[0].contextRoots, unorderedEquals([contextRoot1]));
                  expect(plugins[1].contextRoots,
                      unorderedEquals([contextRoot1, contextRoot2]));
                }
                await manager.stopAll();
              });
        });
    pkg1Dir.deleteSync(recursive: true);
  }

  ContextRootImpl _newContextRoot(String root) {
    throw UnimplementedError();
  }
}

@reflectiveTest
class PluginManagerTest with ResourceProviderMixin, _ContextRoot {
  late String byteStorePath;
  late String sdkPath;
  late TestNotificationManager notificationManager;
  late PluginManager manager;

  void setUp() {
    byteStorePath = resourceProvider.convertPath('/byteStore');
    sdkPath = resourceProvider.convertPath('/sdk');
    notificationManager = TestNotificationManager();
    manager = PluginManager(resourceProvider, byteStorePath, sdkPath,
        notificationManager, InstrumentationService.NULL_SERVICE);
  }

  void test_broadcastRequest_none() {
    var contextRoot = _newContextRoot('/pkg1');
    var responses = manager.broadcastRequest(
        CompletionGetSuggestionsParams('/pkg1/lib/pkg1.dart', 100),
        contextRoot: contextRoot);
    expect(responses, hasLength(0));
  }

  void test_creation() {
    expect(manager.resourceProvider, resourceProvider);
    expect(manager.byteStorePath, byteStorePath);
    expect(manager.sdkPath, sdkPath);
    expect(manager.notificationManager, notificationManager);
  }

  void test_pathsFor_withPackageConfigJsonFile() {
    //
    // Build the minimal directory structure for a plugin package that includes
    // a '.dart_tool/package_config.json' file.
    //
    var pluginDirPath = newFolder('/plugin').path;
    var pluginFile = newFile('/plugin/bin/plugin.dart', '');
    var packageConfigFile = newPackageConfigJsonFile('/plugin', '');
    //
    // Test path computation.
    //
    var files = manager.filesFor(pluginDirPath);
    expect(files.execution, pluginFile);
    expect(files.packages, packageConfigFile);
  }

  void test_pathsFor_withPubspec_inBlazeWorkspace() {
    //
    // Build a Blaze workspace containing four packages, including the plugin.
    //
    newFile('/workspaceRoot/${file_paths.blazeWorkspaceMarker}', '');
    newFolder('/workspaceRoot/blaze-bin');
    newFolder('/workspaceRoot/blaze-genfiles');

    String newPackage(String packageName, [List<String>? dependencies]) {
      var packageRoot =
          newFolder('/workspaceRoot/third_party/dart/$packageName').path;
      newFile('$packageRoot/lib/$packageName.dart', '');
      var buffer = StringBuffer();
      if (dependencies != null) {
        buffer.writeln('dependencies:');
        for (var dependency in dependencies) {
          buffer.writeln('  $dependency: any');
        }
      }
      newPubspecYamlFile(packageRoot, buffer.toString());
      return packageRoot;
    }

    var pluginDirPath = newPackage('plugin', ['b', 'c']);
    var bRootPath = newPackage('b', ['d']);
    var cRootPath = newPackage('c', ['d']);
    var dRootPath = newPackage('d');
    var pluginFile = newFile('$pluginDirPath/bin/plugin.dart', '');
    //
    // Test path computation.
    //
    var files = manager.filesFor(pluginDirPath);
    expect(files.execution, pluginFile);
    var packagesFile = files.packages;
    expect(packagesFile.exists, isTrue);

    var content = packagesFile.readAsStringSync();
    expect(content, '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "b",
      "rootUri": "${toUriStr(bRootPath)}",
      "packageUri": "lib/"
    },
    {
      "name": "c",
      "rootUri": "${toUriStr(cRootPath)}",
      "packageUri": "lib/"
    },
    {
      "name": "d",
      "rootUri": "${toUriStr(dRootPath)}",
      "packageUri": "lib/"
    },
    {
      "name": "plugin",
      "rootUri": "${toUriStr(pluginDirPath)}",
      "packageUri": "lib/"
    }
  ]
}
''');
  }

  void test_pluginsForContextRoot_none() {
    var contextRoot = _newContextRoot('/pkg1');
    expect(manager.pluginsForContextRoot(contextRoot), isEmpty);
  }

  void test_stopAll_none() {
    manager.stopAll();
  }
}

@reflectiveTest
class PluginSessionFromDiskTest extends PluginTestSupport {
  @SkippedTest(
      reason: 'flaky timeouts',
      issue: 'https://github.com/dart-lang/sdk/issues/38629')
  Future<void> test_start_notRunning() async {
    await withPlugin(test: (String pluginPath) async {
      var packagesPath = path.join(pluginPath, '.packages');
      var mainPath = path.join(pluginPath, 'bin', 'plugin.dart');
      var byteStorePath = path.join(pluginPath, 'byteStore');
      io.Directory(byteStorePath).createSync();
      PluginInfo plugin = DiscoveredPluginInfo(
          pluginPath,
          mainPath,
          packagesPath,
          notificationManager,
          InstrumentationService.NULL_SERVICE);
      var session = PluginSession(plugin);
      plugin.currentSession = session;
      expect(await session.start(byteStorePath, ''), isTrue);
      await session.stop();
    });
  }
}

@reflectiveTest
class PluginSessionTest with ResourceProviderMixin {
  late TestNotificationManager notificationManager;
  late String pluginPath;
  late String executionPath;
  late String packagesPath;
  late String sdkPath;
  late PluginInfo plugin;
  late PluginSession session;

  void setUp() {
    notificationManager = TestNotificationManager();
    pluginPath = resourceProvider.convertPath('/pluginDir');
    executionPath = resourceProvider.convertPath('/pluginDir/bin/plugin.dart');
    packagesPath = resourceProvider.convertPath('/pluginDir/.packages');
    sdkPath = resourceProvider.convertPath('/sdk');
    plugin = DiscoveredPluginInfo(pluginPath, executionPath, packagesPath,
        notificationManager, InstrumentationService.NULL_SERVICE);
    session = PluginSession(plugin);
  }

  void test_handleNotification() {
    var notification =
        AnalysisErrorsParams('/test.dart', <AnalysisError>[]).toNotification();
    expect(notificationManager.notifications, hasLength(0));
    session.handleNotification(notification);
    expect(notificationManager.notifications, hasLength(1));
    expect(notificationManager.notifications[0], notification);
  }

  void test_handleOnDone() {
    var channel = TestServerCommunicationChannel(session);
    session.handleOnDone();
    expect(channel.closeCount, 1);
    expect(session.pluginStoppedCompleter.isCompleted, isTrue);
  }

  @failingTest
  void test_handleOnError() {
    session.handleOnError(<String>['message', 'trace']);
    fail('The method handleOnError is not implemented');
  }

  Future<void> test_handleResponse() async {
    TestServerCommunicationChannel(session);
    var response = PluginVersionCheckResult(true, 'name', 'version', <String>[],
            contactInfo: 'contactInfo')
        .toResponse('0', 1);
    var future = session.sendRequest(PluginVersionCheckParams('', '', ''));
    expect(session.pendingRequests, hasLength(1));
    session.handleResponse(response);
    expect(session.pendingRequests, hasLength(0));
    var result = await future;
    expect(result, same(response));
  }

  void test_nextRequestId() {
    expect(session.requestId, 0);
    expect(session.nextRequestId, '0');
    expect(session.requestId, 1);
  }

  void test_sendRequest() {
    var channel = TestServerCommunicationChannel(session);
    session.sendRequest(PluginVersionCheckParams('', '', ''));
    expect(channel.sentRequests, hasLength(1));
    expect(channel.sentRequests[0].method, 'plugin.versionCheck');
  }

  Future<void> test_start_notCompatible() async {
    session.isCompatible = false;
    expect(await session.start(path.join(pluginPath, 'byteStore'), sdkPath),
        isFalse);
  }

  Future<void> test_start_running() async {
    TestServerCommunicationChannel(session);
    try {
      await session.start('', '');
      fail('Expected a StateError to be thrown');
    } on StateError {
      // Expected behavior
    }
  }

  void test_stop_notRunning() {
    expect(() => session.stop(), throwsStateError);
  }

  Future<void> test_stop_running() async {
    var channel = TestServerCommunicationChannel(session);
    await session.stop();
    expect(channel.sentRequests, hasLength(1));
    expect(channel.sentRequests[0].method, 'plugin.shutdown');
  }
}

/// A class designed to be used as a superclass for test classes that define
/// tests that require plugins to be created on disk.
abstract class PluginTestSupport {
  late PhysicalResourceProvider resourceProvider;
  late TestNotificationManager notificationManager;

  /// The content to be used for the '.packages' file, or `null` if the content
  /// has not yet been computed.
  String? _packagesFileContent;

  void setUp() {
    resourceProvider = PhysicalResourceProvider.INSTANCE;
    notificationManager = TestNotificationManager();
  }

  /// Create a directory structure representing a plugin on disk, run the given
  /// [test] function, and then remove the directory. The directory will have
  /// the following structure:
  /// ```
  /// pluginDirectory
  ///   .packages
  ///   bin
  ///     plugin.dart
  /// ```
  /// The name of the plugin directory will be the [pluginName], if one is
  /// provided (in order to allow more than one plugin to be created by a single
  /// test). The 'plugin.dart' file will contain the given [content], or default
  /// content that implements a minimal plugin if the contents are not given.
  /// The [test] function will be passed the path of the directory that was
  /// created.
  Future<void> withPlugin(
      {String? content,
      String? pluginName,
      required Future<void> Function(String) test}) async {
    var tempDirectory =
        io.Directory.systemTemp.createTempSync(pluginName ?? 'test_plugin');
    try {
      var pluginPath = tempDirectory.resolveSymbolicLinksSync();
      //
      // Create a .packages file.
      //
      var packagesFile = io.File(path.join(pluginPath, '.packages'));
      packagesFile.writeAsStringSync(_getPackagesFileContent());
      //
      // Create the 'bin' directory.
      //
      var binPath = path.join(pluginPath, 'bin');
      io.Directory(binPath).createSync();
      //
      // Create the 'plugin.dart' file.
      //
      var pluginFile = io.File(path.join(binPath, 'plugin.dart'));
      pluginFile.writeAsStringSync(content ?? _defaultPluginContent());
      //
      // Run the actual test code.
      //
      await test(pluginPath);
    } finally {
      tempDirectory.deleteSync(recursive: true);
    }
  }

  /// Create a directory structure representing a plugin on disk, run the given
  /// [test] function, and then remove the directory. The directory will have
  /// the following structure:
  /// ```
  /// pluginDirectory
  ///   pubspec.yaml
  ///   bin
  ///     plugin.dart
  /// ```
  /// The name of the plugin directory will be the [pluginName], if one is
  /// provided (in order to allow more than one plugin to be created by a single
  /// test). The 'plugin.dart' file will contain the given [content], or default
  /// content that implements a minimal plugin if the contents are not given.
  /// The [test] function will be passed the path of the directory that was
  /// created.
  Future<void> withPubspecPlugin(
      {String? content,
      String? pluginName,
      required Future<void> Function(String) test}) async {
    var tempDirectory =
        io.Directory.systemTemp.createTempSync(pluginName ?? 'test_plugin');
    try {
      var pluginPath = tempDirectory.resolveSymbolicLinksSync();
      //
      // Create a pubspec.yaml file.
      //
      var pubspecFile = io.File(path.join(pluginPath, file_paths.pubspecYaml));
      pubspecFile.writeAsStringSync(_getPubspecFileContent());
      //
      // Create the 'bin' directory.
      //
      var binPath = path.join(pluginPath, 'bin');
      io.Directory(binPath).createSync();
      //
      // Create the 'plugin.dart' file.
      //
      var pluginFile = io.File(path.join(binPath, 'plugin.dart'));
      pluginFile.writeAsStringSync(content ?? _defaultPluginContent());
      //
      // Run the actual test code.
      //
      await test(pluginPath);
    } finally {
      tempDirectory.deleteSync(recursive: true);
    }
  }

  /// Convert the [sdkPackageMap] into a plugin-specific map by applying the
  /// given relative path [delta] to each line.
  String _convertPackageMap(String sdkDirPath, List<String> sdkPackageMap) {
    var buffer = StringBuffer();
    for (var line in sdkPackageMap) {
      if (!line.startsWith('#')) {
        var index = line.indexOf(':');
        var packageName = line.substring(0, index + 1);
        var relativePath = line.substring(index + 1);
        var absolutePath = path.join(sdkDirPath, relativePath);
        // Convert to file:/// URI since that's how absolute paths in
        // .packages must be for windows
        absolutePath = Uri.file(absolutePath).toString();
        buffer.write(packageName);
        buffer.writeln(absolutePath);
      }
    }
    return buffer.toString();
  }

  /// The default content of the plugin. This is a minimal plugin that will only
  /// respond correctly to version checks and to shutdown requests.
  String _defaultPluginContent() {
    return r'''
import 'dart:async';
import 'dart:isolate';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/plugin/plugin.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/starter.dart';
import 'package:pub_semver/pub_semver.dart';

void main(List<String> args, SendPort sendPort) {
  MinimalPlugin plugin = new MinimalPlugin(PhysicalResourceProvider.INSTANCE);
  new ServerPluginStarter(plugin).start(sendPort);
}

class MinimalPlugin extends ServerPlugin {
  MinimalPlugin(ResourceProvider provider) : super(provider);

  @override
  List<String> get fileGlobsToAnalyze => <String>['**/*.dart'];

  @override
  String get name => 'minimal';

  @override
  String get version => '0.0.1';

  @override
  AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot) => null;

  @override
  Future<AnalysisHandleWatchEventsResult> handleAnalysisHandleWatchEvents(
      AnalysisHandleWatchEventsParams parameters) async =>
    new AnalysisHandleWatchEventsResult();

  @override
  bool isCompatibleWith(Version serverVersion) => true;
}
''';
  }

  /// Return the content to be used for the '.packages' file.
  String _getPackagesFileContent() {
    var packagesFileContent = _packagesFileContent;
    if (packagesFileContent == null) {
      var sdkPackagesFile = io.File(_sdkPackagesPath());
      var sdkPackageMap = sdkPackagesFile.readAsLinesSync();
      packagesFileContent = _packagesFileContent =
          _convertPackageMap(path.dirname(sdkPackagesFile.path), sdkPackageMap);
    }
    return packagesFileContent;
  }

  /// Return the content to be used for the 'pubspec.yaml' file.
  String _getPubspecFileContent() {
    return '''
name: 'test'
dependencies:
  analyzer: any
  analyzer_plugin: any
''';
  }

  /// Return the path to the '.packages' file in the root of the SDK checkout.
  String _sdkPackagesPath() {
    var packagesPath = io.Platform.script.toFilePath();
    while (packagesPath.isNotEmpty &&
        path.basename(packagesPath) != 'analysis_server') {
      packagesPath = path.dirname(packagesPath);
    }
    packagesPath = path.dirname(packagesPath);
    packagesPath = path.dirname(packagesPath);
    return path.join(packagesPath, '.packages');
  }
}

class TestNotificationManager implements AbstractNotificationManager {
  List<Notification> notifications = <Notification>[];

  Map<String, Map<String, List<AnalysisError>>> recordedErrors =
      <String, Map<String, List<AnalysisError>>>{};

  @override
  void handlePluginNotification(String pluginId, Notification notification) {
    notifications.add(notification);
  }

  @override
  dynamic noSuchMethod(Invocation invocation) {
    fail('Unexpected invocation of ${invocation.memberName}');
  }

  @override
  void recordAnalysisErrors(
      String pluginId, String filePath, List<AnalysisError> errorData) {
    recordedErrors.putIfAbsent(
        pluginId, () => <String, List<AnalysisError>>{})[filePath] = errorData;
  }
}

class TestServerCommunicationChannel implements ServerCommunicationChannel {
  final PluginSession session;
  int closeCount = 0;
  List<Request> sentRequests = <Request>[];

  TestServerCommunicationChannel(this.session) {
    session.channel = this;
  }

  @override
  void close() {
    closeCount++;
  }

  @override
  void kill() {
    fail('Unexpected invocation of kill');
  }

  @override
  void listen(void Function(Response response) onResponse,
      void Function(Notification notification) onNotification,
      {void Function(dynamic error)? onError, void Function()? onDone}) {
    fail('Unexpected invocation of listen');
  }

  @override
  void sendRequest(Request request) {
    sentRequests.add(request);
    if (request.method == 'plugin.shutdown') {
      session.handleOnDone();
    }
  }
}

mixin _ContextRoot on ResourceProviderMixin {
  ContextRootImpl _newContextRoot(String root) {
    root = convertPath(root);
    return ContextRootImpl(
      resourceProvider,
      resourceProvider.getFolder(root),
      BasicWorkspace.find(resourceProvider, Packages.empty, root),
    );
  }
}
