// 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:collection/collection.dart';
import 'package:dds/dap.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_adapter.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_test_adapter.dart';

/// A [FlutterDebugAdapter] that captures what process/args will be launched.
class MockFlutterDebugAdapter extends FlutterDebugAdapter {
  factory MockFlutterDebugAdapter({
    required FileSystem fileSystem,
    required Platform platform,
    bool simulateAppStarted = true,
    FutureOr<void> Function(MockFlutterDebugAdapter adapter)? preAppStart,
  }) {
    final StreamController<List<int>> stdinController = StreamController<List<int>>();
    final StreamController<List<int>> stdoutController = StreamController<List<int>>();
    final ByteStreamServerChannel channel = ByteStreamServerChannel(stdinController.stream, stdoutController.sink, null);
    final ByteStreamServerChannel clientChannel = ByteStreamServerChannel(stdoutController.stream, stdinController.sink, null);

    return MockFlutterDebugAdapter._(
      channel,
      clientChannel: clientChannel,
      fileSystem: fileSystem,
      platform: platform,
      simulateAppStarted: simulateAppStarted,
      preAppStart: preAppStart,
    );
  }

  MockFlutterDebugAdapter._(
    super.channel, {
    required this.clientChannel,
    required super.fileSystem,
    required super.platform,
    this.simulateAppStarted = true,
    this.preAppStart,
  }) {
    clientChannel.listen((ProtocolMessage message) {
      _handleDapToClientMessage(message);
    });
  }

  int _seq = 1;
  final ByteStreamServerChannel clientChannel;
  final bool simulateAppStarted;
  final FutureOr<void> Function(MockFlutterDebugAdapter adapter)? preAppStart;

  late String executable;
  late List<String> processArgs;
  late Map<String, String>? env;

  final StreamController<Map<String, Object?>> _dapToClientMessagesController = StreamController<Map<String, Object?>>.broadcast();

  /// A stream of all messages sent from the adapter back to the client.
  Stream<Map<String, Object?>> get dapToClientMessages => _dapToClientMessagesController.stream;

  /// A stream of all progress events sent from the adapter back to the client.
  Stream<Map<String, Object?>> get dapToClientProgressEvents {
    const List<String> progressEventTypes = <String>['progressStart', 'progressUpdate', 'progressEnd'];

    return dapToClientMessages
        .where((Map<String, Object?> message) => progressEventTypes.contains(message['event'] as String?));
  }

  /// A list of all messages sent from the adapter to the `flutter run` processes `stdin`.
  final List<Map<String, Object?>> dapToFlutterMessages = <Map<String, Object?>>[];

  /// The `method`s of all mesages sent to the `flutter run` processes `stdin`
  /// by the debug adapter.
  List<String> get dapToFlutterRequests => dapToFlutterMessages
      .map((Map<String, Object?> message) => message['method'] as String?)
      .whereNotNull()
      .toList();

  /// A handler for the 'app.exposeUrl' reverse-request.
  String Function(String)? exposeUrlHandler;

  @override
  Future<void> launchAsProcess({
    required String executable,
    required List<String> processArgs,
    required Map<String, String>? env,
  }) async {
    this.executable = executable;
    this.processArgs = processArgs;
    this.env = env;

    await preAppStart?.call(this);

    // Simulate the app starting by triggering handling of events that Flutter
    // would usually write to stdout.
    if (simulateAppStarted) {
      simulateStdoutMessage(<String, Object?>{
        'event': 'app.started',
      });
      simulateStdoutMessage(<String, Object?>{
        'event': 'app.start',
        'params': <String, Object?>{
          'appId': 'TEST',
        }
      });
    }
  }

  /// Handles messages sent from the debug adapter back to the client.
  void _handleDapToClientMessage(ProtocolMessage message) {
    _dapToClientMessagesController.add(message.toJson());

    // Pretend to be the client, delegating any reverse-requests to the relevant
    // handler that is provided by the test.
    if (message is Event && message.event == 'flutter.forwardedRequest') {
      final Map<String, Object?> body = message.body! as Map<String, Object?>;
      final String method = body['method']! as String;
      final Map<String, Object?>? params = body['params'] as Map<String, Object?>?;

      final Object? result = _handleReverseRequest(method, params);

      // Send the result back in the same way the client would.
      clientChannel.sendRequest(Request(
        seq: _seq++,
        command: 'flutter.sendForwardedRequestResponse',
        arguments: <String, Object?>{
          'id': body['id'],
          'result': result,
        },
      ));
    }
  }

  Object? _handleReverseRequest(String method, Map<String, Object?>? params) {
    switch (method) {
      case 'app.exposeUrl':
        final String url = params!['url']! as String;
        return exposeUrlHandler!(url);
      default:
        throw ArgumentError('Reverse-request $method is unknown');
    }
  }

  /// Simulates a message emitted by the `flutter run` process by directly
  /// calling the debug adapters [handleStdout] method.
  ///
  /// Use [simulateRawStdout] to simulate non-daemon text output.
  void simulateStdoutMessage(Map<String, Object?> message) {
    // Messages are wrapped in a list because Flutter only processes messages
    // wrapped in brackets.
    handleStdout(jsonEncode(<Object?>[message]));
  }

  /// Simulates a string emitted by the `flutter run` process by directly
  /// calling the debug adapters [handleStdout] method.
  ///
  /// Use [simulateStdoutMessage] to simulate a daemon JSON message.
  void simulateRawStdout(String output) {
    handleStdout(output);
  }

  @override
  void sendFlutterMessage(Map<String, Object?> message) {
    dapToFlutterMessages.add(message);
    // Don't call super because it will try to write to the process that we
    // didn't actually spawn.
  }

  @override
  Future<void> get debuggerInitialized {
    // If we were mocking debug mode, then simulate the debugger initializing.
    return enableDebugger
        ? Future<void>.value()
        : throw StateError('Invalid attempt to wait for debuggerInitialized when not debugging');
  }
}

/// A [FlutterTestDebugAdapter] that captures what process/args will be launched.
class MockFlutterTestDebugAdapter extends FlutterTestDebugAdapter {
  factory MockFlutterTestDebugAdapter({
    required FileSystem fileSystem,
    required Platform platform,
  }) {
    final StreamController<List<int>> stdinController = StreamController<List<int>>();
    final StreamController<List<int>> stdoutController = StreamController<List<int>>();
    final ByteStreamServerChannel channel = ByteStreamServerChannel(stdinController.stream, stdoutController.sink, null);

    return MockFlutterTestDebugAdapter._(
      stdinController.sink,
      stdoutController.stream,
      channel,
      fileSystem: fileSystem,
      platform: platform,
    );
  }

  MockFlutterTestDebugAdapter._(
    this.stdin,
    this.stdout,
    ByteStreamServerChannel channel, {
    required FileSystem fileSystem,
    required Platform platform,
  }) : super(channel, fileSystem: fileSystem, platform: platform);

  final StreamSink<List<int>> stdin;
  final Stream<List<int>> stdout;

  late String executable;
  late List<String> processArgs;
  late Map<String, String>? env;

  @override
  Future<void> launchAsProcess({
    required String executable,
    required List<String> processArgs,
    required Map<String, String>? env,
  }) async {
    this.executable = executable;
    this.processArgs = processArgs;
    this.env = env;
  }

  @override
  Future<void> get debuggerInitialized {
    // If we were mocking debug mode, then simulate the debugger initializing.
    return enableDebugger
        ? Future<void>.value()
        : throw StateError('Invalid attempt to wait for debuggerInitialized when not debugging');
  }
}

class MockRequest extends Request {
  MockRequest()
      : super.fromMap(<String, Object?>{
          'command': 'mock_command',
          'type': 'mock_type',
          'seq': _requestId++,
        });

  static int _requestId = 1;
}
