// Copyright 2014 The Flutter Authors. 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:dds/dds.dart' as dds;
import 'package:meta/meta.dart';

import 'common.dart';
import 'context.dart';
import 'io.dart' as io;
import 'logger.dart';

// TODO(fujino): This should be direct injected, rather than mutable global state.
@visibleForTesting
Future<dds.DartDevelopmentService> Function(
  Uri remoteVmServiceUri, {
  bool enableAuthCodes,
  bool ipv6,
  Uri? serviceUri,
  List<String> cachedUserTags,
  dds.UriConverter? uriConverter,
}) ddsLauncherCallback = dds.DartDevelopmentService.startDartDevelopmentService;

/// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to
/// mock out this functionality for testing purposes.
class DartDevelopmentService {
  dds.DartDevelopmentService? _ddsInstance;

  Uri? get uri => _ddsInstance?.uri ?? _existingDdsUri;
  Uri? _existingDdsUri;

  Future<void> get done => _completer.future;
  final Completer<void> _completer = Completer<void>();

  Future<void> startDartDevelopmentService(
    Uri observatoryUri, {
    required Logger logger,
    int? hostPort,
    bool? ipv6,
    bool? disableServiceAuthCodes,
    bool cacheStartupProfile = false,
  }) async {
    final Uri ddsUri = Uri(
      scheme: 'http',
      host: ((ipv6 ?? false) ? io.InternetAddress.loopbackIPv6 : io.InternetAddress.loopbackIPv4).host,
      port: hostPort ?? 0,
    );
    logger.printTrace(
      'Launching a Dart Developer Service (DDS) instance at $ddsUri, '
      'connecting to VM service at $observatoryUri.',
    );
    try {
      _ddsInstance = await ddsLauncherCallback(
          observatoryUri,
          serviceUri: ddsUri,
          enableAuthCodes: disableServiceAuthCodes != true,
          ipv6: ipv6 ?? false,
          // Enables caching of CPU samples collected during application startup.
          cachedUserTags: cacheStartupProfile ? const <String>['AppStartUp'] : const <String>[],
          uriConverter: context.get<dds.UriConverter>(),
        );
      unawaited(_ddsInstance?.done.whenComplete(() {
        if (!_completer.isCompleted) {
          _completer.complete();
        }
      }));
      logger.printTrace('DDS is listening at ${_ddsInstance?.uri}.');
    } on dds.DartDevelopmentServiceException catch (e) {
      logger.printTrace('Warning: Failed to start DDS: ${e.message}');
      if (e.errorCode == dds.DartDevelopmentServiceException.existingDdsInstanceError) {
        try {
          // First try to use the new field to avoid parsing from the message.
          _existingDdsUri = e is dds.ExistingDartDevelopmentServiceException ? e.ddsUri : null;

            // Otherwise, fall back to parsing from the exception (old DDS).
            // This is not completely reliable which is why the new field above
            // was added.
            if (_existingDdsUri == null) {
              String parsedUrl = e.message.split(' ').firstWhere((String e) => e.startsWith('http'));
              // Trim trailing full stops from the message.
              // https://github.com/flutter/flutter/issues/118609.
              if (parsedUrl.endsWith('.')) {
                parsedUrl = parsedUrl.substring(0, parsedUrl.length - 1);
              }
              _existingDdsUri ??= Uri.parse(parsedUrl);
            }
        } on StateError {
          if (e.message.contains('Existing VM service clients prevent DDS from taking control.')) {
            throwToolExit('${e.message}. Please rebuild your application with a newer version of Flutter.');
          }
          logger.printError(
            'DDS has failed to start and there is not an existing DDS instance '
            'available to connect to. Please file an issue at https://github.com/flutter/flutter/issues '
            'with the following error message:\n\n ${e.message}.'
          );
          // DDS was unable to start for an unknown reason. Raise a StateError
          // so it can be reported by the crash reporter.
          throw StateError(e.message);
        }
      }
      if (!_completer.isCompleted) {
        _completer.complete();
      }
      rethrow;
    }
  }

  Future<void> shutdown() async => _ddsInstance?.shutdown();
}
