// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analytics/analytics_manager.dart';
import 'package:analysis_server/src/legacy_analysis_server.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/error_notifier.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unified_analytics/unified_analytics.dart';

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

@reflectiveTest
class AnalysisServerTest with ResourceProviderMixin {
  @override
  MemoryResourceProvider resourceProvider = MemoryResourceProvider(
    // Force the in-memory file watchers to be slowly initialized to emulate
    // the physical watchers (for test_concurrentContextRebuilds).
    delayWatcherInitialization: Duration(milliseconds: 1),
  );

  late MockServerChannel channel;
  late ErrorNotifier errorNotifier;
  late LegacyAnalysisServer server;

  void setUp() {
    channel = MockServerChannel();

    // Create an SDK in the mock file system.
    var sdkRoot = newFolder('/sdk');
    createMockSdk(resourceProvider: resourceProvider, root: sdkRoot);

    errorNotifier = ErrorNotifier();
    server = LegacyAnalysisServer(
      channel,
      resourceProvider,
      AnalysisServerOptions(),
      DartSdkManager(sdkRoot.path),
      AnalyticsManager(NoOpAnalytics()),
      CrashReportingAttachmentsBuilder.empty,
      errorNotifier,
    );
    errorNotifier.server = server;
  }

  /// See https://github.com/dart-lang/sdk/issues/50496
  Future<void> test_caching_mixin_superInvokedNames_setter_change() async {
    var lib = convertPath('/lib');
    newFolder(lib);
    var foo = newFile('/lib/foo.dart', '''
class A {
  set foo(int _) {}
}
mixin M on A {
  void bar() {
    super.boo = 0;
  }
}
class X extends A with M {}
''');
    await server.setAnalysisRoots('0', [lib], []);
    await server.onAnalysisComplete;
    expect(server.statusAnalyzing, isFalse);
    channel.notificationsReceived.clear();

    server.updateContent('0', {
      foo.path: AddContentOverlay('''
class A {
  set foo(int _) {}
}
mixin M on A {
  void bar() {
    super.foo = 0;
  }
}
class X extends A with M {}
'''),
    });
    await server.onAnalysisComplete;
    expect(server.statusAnalyzing, isFalse);
    var notifications = channel.notificationsReceived;
    expect(notifications, hasLength(1));
    var notification = notifications.first;
    expect(notification.event, 'analysis.errors');
    var params = notification.params!;
    var errors = params['errors'] as List<Map<String, Object?>>;
    expect(errors, isEmpty);
  }

  /// Test that modifying package_config again while a context rebuild is in
  /// progress does not get lost due to a gap between creating a file watcher
  /// and it raising events.
  /// https://github.com/Dart-Code/Dart-Code/issues/3438
  Future<void> test_concurrentContextRebuilds() async {
    // Subscribe to STATUS so we'll know when analysis is done.
    server.serverServices = {ServerService.STATUS};
    var projectRoot = convertPath('/foo');
    var projectTestFile = convertPath('/foo/lib/test.dart');
    var projectPackageConfigFile = convertPath(
      '/foo/.dart_tool/package_config.json',
    );

    // Create a file that references two packages, which will we write to
    // package_config.json individually.
    newFolder(projectRoot);
    newFile(projectTestFile, r'''
      import "package:foo/foo.dart";'
      import "package:bar/bar.dart";'
      ''');

    // Ensure the packages and package_config exist.
    var fooLibFolder = _addSimplePackage('foo', '');
    var barLibFolder = _addSimplePackage('bar', '');
    var config = PackageConfigFileBuilder();
    writePackageConfig(projectPackageConfigFile, config);

    // Track diagnostics that arrive.
    var errorsByFile = <String, List<AnalysisError>>{};
    channel.notifications
        .where((notification) => notification.event == 'analysis.errors')
        .listen((notification) {
          var params = AnalysisErrorsParams.fromNotification(
            notification,
            clientUriConverter: server.uriConverter,
          );
          errorsByFile[params.file] = params.errors;
        });

    /// Helper that waits for analysis then returns the relevant errors.
    Future<List<AnalysisError>> getUriNotExistErrors() async {
      await server.onAnalysisComplete;
      expect(server.statusAnalyzing, isFalse);
      return errorsByFile[projectTestFile]!
          .where((error) => error.code == 'uri_does_not_exist')
          .toList();
    }

    // Set roots and expect 2 uri_does_not_exist errors.
    await server.setAnalysisRoots('0', [projectRoot], []);
    expect(await getUriNotExistErrors(), hasLength(2));

    // Write both packages, in two events so that the first one will trigger
    // a rebuild.
    config.add(name: 'foo', rootPath: fooLibFolder.parent.path);
    writePackageConfig(projectPackageConfigFile, config);
    await pumpEventQueue(times: 1); // Allow server to begin processing.
    config.add(name: 'bar', rootPath: barLibFolder.parent.path);
    writePackageConfig(projectPackageConfigFile, config);

    // Eventually the errors are gone.
    while (true) {
      var errors = await getUriNotExistErrors();
      if (errors.isEmpty) {
        break;
      }
      await pumpEventQueue(times: 5000);
    }
  }

  Future<void> test_errorNotification_errorNotifier() async {
    errorNotifier.logException(Exception('dummy exception'));

    var errors = channel.notificationsReceived.where(
      (notification) => notification.event == SERVER_NOTIFICATION_ERROR,
    );
    expect(
      errors.single.params![SERVER_NOTIFICATION_ERROR_MESSAGE],
      contains('dummy exception'),
    );
  }

  Future<void> test_errorNotification_sendNotification() async {
    server.sendServerErrorNotification(
      'message',
      Exception('dummy exception'),
      null,
    );

    var errors = channel.notificationsReceived.where(
      (notification) => notification.event == SERVER_NOTIFICATION_ERROR,
    );
    expect(
      errors.single.params![SERVER_NOTIFICATION_ERROR_MESSAGE],
      contains('dummy exception'),
    );
  }

  Future<void> test_serverStatusNotifications_hasFile() async {
    server.serverServices.add(ServerService.STATUS);

    newFile('/test/lib/a.dart', r'''
class A {}
''');
    await server.setAnalysisRoots('0', [convertPath('/test')], []);

    // Pump the event queue, so that the server has finished any analysis.
    await pumpEventQueue(times: 5000);

    var notifications = channel.notificationsReceived;
    expect(notifications, isNotEmpty);

    // At least one notification indicating analysis is in progress.
    expect(
      notifications.any((Notification notification) {
        if (notification.event == SERVER_NOTIFICATION_STATUS) {
          var params = ServerStatusParams.fromNotification(
            notification,
            clientUriConverter: server.uriConverter,
          );
          var analysis = params.analysis;
          if (analysis != null) {
            return analysis.isAnalyzing;
          }
        }
        return false;
      }),
      isTrue,
    );

    // The last notification should indicate that analysis is complete.
    var notification = notifications[notifications.length - 1];
    var params = ServerStatusParams.fromNotification(
      notification,
      clientUriConverter: server.uriConverter,
    );
    expect(params.analysis!.isAnalyzing, isFalse);
  }

  Future<void> test_serverStatusNotifications_noFiles() async {
    server.serverServices.add(ServerService.STATUS);

    newFolder('/test');
    await server.setAnalysisRoots('0', [convertPath('/test')], []);

    // Pump the event queue, so that the server has finished any analysis.
    await pumpEventQueue(times: 5000);

    var notifications = channel.notificationsReceived;
    expect(notifications, isNotEmpty);

    // At least one notification indicating analysis is in progress.
    expect(
      notifications.any((Notification notification) {
        if (notification.event == SERVER_NOTIFICATION_STATUS) {
          var params = ServerStatusParams.fromNotification(
            notification,
            clientUriConverter: server.uriConverter,
          );
          var analysis = params.analysis;
          if (analysis != null) {
            return analysis.isAnalyzing;
          }
        }
        return false;
      }),
      isTrue,
    );

    // The last notification should indicate that analysis is complete.
    var notification = notifications[notifications.length - 1];
    var params = ServerStatusParams.fromNotification(
      notification,
      clientUriConverter: server.uriConverter,
    );
    expect(params.analysis!.isAnalyzing, isFalse);
  }

  Future<void>
  test_setAnalysisSubscriptions_fileInIgnoredFolder_newOptions() async {
    var path = convertPath('/project/samples/sample.dart');
    newFile(path, '');
    newAnalysisOptionsYamlFile('/project', r'''
analyzer:
  exclude:
    - 'samples/**'
''');
    await server.setAnalysisRoots('0', [convertPath('/project')], []);
    server.setAnalysisSubscriptions(<AnalysisService, Set<String>>{
      AnalysisService.NAVIGATION: <String>{path},
    });

    // We respect subscriptions, even for excluded files.
    await pumpEventQueue(times: 5000);
    expect(
      channel.notificationsReceived.any((notification) {
        return notification.event == ANALYSIS_NOTIFICATION_NAVIGATION;
      }),
      isTrue,
    );
  }

  Future<void>
  test_setAnalysisSubscriptions_fileInIgnoredFolder_oldOptions() async {
    var path = convertPath('/project/samples/sample.dart');
    newFile(path, '');
    newAnalysisOptionsYamlFile('/project', r'''
analyzer:
  exclude:
    - 'samples/**'
''');
    await server.setAnalysisRoots('0', [convertPath('/project')], []);
    server.setAnalysisSubscriptions(<AnalysisService, Set<String>>{
      AnalysisService.NAVIGATION: <String>{path},
    });

    // We respect subscriptions, even for excluded files.
    await pumpEventQueue(times: 5000);
    expect(
      channel.notificationsReceived.any((notification) {
        return notification.event == ANALYSIS_NOTIFICATION_NAVIGATION;
      }),
      isTrue,
    );
  }

  Future<void> test_shutdown() {
    var request = Request('my28', SERVER_REQUEST_SHUTDOWN);
    return channel.simulateRequestFromClient(request).then((Response response) {
      expect(response.id, equals('my28'));
      expect(response.error, isNull);
    });
  }

  Future<void> test_unknownRequest() {
    var request = Request('my22', 'randomRequest');
    return channel.simulateRequestFromClient(request).then((Response response) {
      expect(response.id, equals('my22'));
      expect(response.error, isNotNull);
    });
  }

  void writePackageConfig(String path, PackageConfigFileBuilder config) {
    newFile(path, config.toContent(toUriStr: toUriStr));
  }

  /// Creates a simple package named [name] with [content] in the file at
  /// `package:$name/$name.dart`.
  ///
  /// Returns a [Folder] that represents the packages `lib` folder.
  Folder _addSimplePackage(String name, String content) {
    var packagePath = '/packages/$name';
    var file = newFile('$packagePath/lib/$name.dart', content);
    return file.parent;
  }
}
