// Copyright (c) 2020, 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_generated.dart'
    hide AnalysisOptions;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.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/instrumentation/instrumentation.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:matcher/matcher.dart';
import 'package:meta/meta.dart';

import '../../mocks.dart';

abstract class AbstractClient {
  final MockServerChannel serverChannel;
  final TestPluginManager pluginManager;
  late AnalysisServer server;

  final List<GeneralAnalysisService> generalServices =
      <GeneralAnalysisService>[];
  final Map<AnalysisService, List<String>> analysisSubscriptions = {};

  final String projectPath;
  final String testFilePath;
  late String testCode;

  late MockSdk sdk;

  final AnalysisServerOptions serverOptions;

  AbstractClient({
    required this.projectPath,
    required this.testFilePath,
    required String sdkPath,
    required this.serverOptions,
  })   : serverChannel = MockServerChannel(),
        pluginManager = TestPluginManager() {
    server = createAnalysisServer(sdkPath);
    var notificationStream = serverChannel.notificationController.stream;
    notificationStream.listen((Notification notification) {
      processNotification(notification);
    });
  }

  AnalysisDomainHandler get analysisHandler =>
      server.handlers.singleWhere((handler) => handler is AnalysisDomainHandler)
          as AnalysisDomainHandler;

  AnalysisOptions get analysisOptions => testDriver.analysisOptions;

  CompletionDomainHandler get completionHandler =>
      server.handlers.whereType<CompletionDomainHandler>().single;

  MemoryResourceProvider get resourceProvider;

  AnalysisDriver get testDriver => server.getAnalysisDriver(testFilePath)!;

  void addAnalysisOptionsFile(String content) {
    newFile(
        resourceProvider.pathContext.join(projectPath, 'analysis_options.yaml'),
        content);
  }

  void addAnalysisSubscription(AnalysisService service, String file) {
    // add file to subscription
    var files = analysisSubscriptions[service];
    if (files == null) {
      files = <String>[];
      analysisSubscriptions[service] = files;
    }
    files.add(file);
    // set subscriptions
    var request =
        AnalysisSetSubscriptionsParams(analysisSubscriptions).toRequest('0');
    handleSuccessfulRequest(request);
  }

  void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
    generalServices.add(service);
    var request =
        AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
    handleSuccessfulRequest(request);
  }

  String addTestFile(String content) {
    newFile(testFilePath, content);
    testCode = content;
    return testFilePath;
  }

  void assertValidId(String id) {
    expect(id, isNotNull);
    expect(id.isNotEmpty, isTrue);
  }

  /// Create an analysis server with the given [sdkPath].
  AnalysisServer createAnalysisServer(String sdkPath) {
    sdk = MockSdk(resourceProvider: resourceProvider);
    return AnalysisServer(
        serverChannel,
        resourceProvider,
        serverOptions,
        DartSdkManager(sdkPath),
        CrashReportingAttachmentsBuilder.empty,
        InstrumentationService.NULL_SERVICE);
  }

  /// Create a project at [projectPath].
  @mustCallSuper
  void createProject({Map<String, String>? packageRoots}) {
    newFolder(projectPath);
    var request = AnalysisSetAnalysisRootsParams([projectPath], [],
            packageRoots: packageRoots)
        .toRequest('0');
    handleSuccessfulRequest(request, handler: analysisHandler);
  }

  void expect(actual, matcher, {String reason});

  /// Validate that the given [request] is handled successfully.
  Response handleSuccessfulRequest(Request request, {RequestHandler? handler}) {
    handler ??= analysisHandler;
    var response = handler.handleRequest(request)!;
    expect(response, isResponseSuccess(request.id));
    return response;
  }

  File newFile(String path, String content, [int stamp]);

  Folder newFolder(String path);

  void processNotification(Notification notification);

  /// Returns a [Future] that completes when the server's analysis is complete.
  Future waitForTasksFinished() => server.onAnalysisComplete;

  /// Completes with a successful [Response] for the given [request].
  /// Otherwise fails.
  Future<Response> waitResponse(Request request,
      {bool throwOnError = true}) async {
    return serverChannel.sendRequest(request, throwOnError: throwOnError);
  }
}
