// 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:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/daemon.dart';

import '../src/common.dart';

class FakeDaemonStreams implements DaemonStreams {
  final StreamController<DaemonMessage> inputs = StreamController<DaemonMessage>();
  final StreamController<DaemonMessage> outputs = StreamController<DaemonMessage>();

  @override
  Stream<DaemonMessage> get inputStream {
    return inputs.stream;
  }

  @override
  void send(Map<String, dynamic> message, [ List<int>? binary ]) {
    outputs.add(DaemonMessage(message, binary != null ? Stream<List<int>>.value(binary) : null));
  }

  @override
  Future<void> dispose() async {
    await inputs.close();
    // In some tests, outputs have no listeners. We don't wait for outputs to close.
    unawaited(outputs.close());
  }
}

void main() {
  late BufferLogger bufferLogger;
  late FakeDaemonStreams daemonStreams;
  late DaemonConnection daemonConnection;
  setUp(() {
    bufferLogger = BufferLogger.test();
    daemonStreams = FakeDaemonStreams();
    daemonConnection = DaemonConnection(
      daemonStreams: daemonStreams,
      logger: bufferLogger,
    );
  });

  tearDown(() async {
    await daemonConnection.dispose();
  });

  group('DaemonConnection receiving end', () {
    testWithoutContext('redirects input to incoming commands', () async {
      final Map<String, dynamic> commandToSend = <String, dynamic>{'id': 0, 'method': 'some_method'};
      daemonStreams.inputs.add(DaemonMessage(commandToSend));

      final DaemonMessage commandReceived = await daemonConnection.incomingCommands.first;
      await daemonStreams.dispose();

      expect(commandReceived.data, commandToSend);
    });

    testWithoutContext('listenToEvent can receive the right events', () async {
      final Future<List<DaemonEventData>> events = daemonConnection.listenToEvent('event1').toList();

      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'event': 'event1', 'params': '1'}));
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'event': 'event2', 'params': '2'}));
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'event': 'event1', 'params': null}));
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'event': 'event1', 'params': 3}));

      await pumpEventQueue();
      await daemonConnection.dispose();

      expect((await events).map((DaemonEventData event) => event.data).toList(), <dynamic>['1', null, 3]);
    });
  });

  group('DaemonConnection sending end', () {
    testWithoutContext('sending requests', () async {
      unawaited(daemonConnection.sendRequest('some_method', 'param'));
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], isNotNull);
      expect(message.data['method'], 'some_method');
      expect(message.data['params'], 'param');
    });

    testWithoutContext('sending requests without param', () async {
      unawaited(daemonConnection.sendRequest('some_method'));
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], isNotNull);
      expect(message.data['method'], 'some_method');
      expect(message.data['params'], isNull);
    });

    testWithoutContext('sending response', () async {
      daemonConnection.sendResponse('1', 'some_data');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], '1');
      expect(message.data['method'], isNull);
      expect(message.data['error'], isNull);
      expect(message.data['result'], 'some_data');
    });

    testWithoutContext('sending response without data', () async {
      daemonConnection.sendResponse('1');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], '1');
      expect(message.data['method'], isNull);
      expect(message.data['error'], isNull);
      expect(message.data['result'], isNull);
    });

    testWithoutContext('sending error response', () async {
      daemonConnection.sendErrorResponse('1', 'error', StackTrace.fromString('stack trace'));
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], '1');
      expect(message.data['method'], isNull);
      expect(message.data['error'], 'error');
      expect(message.data['trace'], 'stack trace');
    });

    testWithoutContext('sending events', () async {
      daemonConnection.sendEvent('some_event', '123');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], isNull);
      expect(message.data['event'], 'some_event');
      expect(message.data['params'], '123');
    });

    testWithoutContext('sending events without params', () async {
      daemonConnection.sendEvent('some_event');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;
      expect(message.data['id'], isNull);
      expect(message.data['event'], 'some_event');
      expect(message.data['params'], isNull);
    });
  });

  group('DaemonConnection request and response', () {
    testWithoutContext('receiving response from requests', () async {
      final Future<dynamic> requestFuture = daemonConnection.sendRequest('some_method', 'param');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;

      expect(message.data['id'], isNotNull);
      expect(message.data['method'], 'some_method');
      expect(message.data['params'], 'param');

      final String id = message.data['id']! as String;
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'id': id, 'result': '123'}));
      expect(await requestFuture, '123');
    });

    testWithoutContext('receiving response from requests without result', () async {
      final Future<dynamic> requestFuture = daemonConnection.sendRequest('some_method', 'param');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;

      expect(message.data['id'], isNotNull);
      expect(message.data['method'], 'some_method');
      expect(message.data['params'], 'param');

      final String id = message.data['id']! as String;
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'id': id}));
      expect(await requestFuture, null);
    });

    testWithoutContext('receiving error response from requests without result', () async {
      final Future<dynamic> requestFuture = daemonConnection.sendRequest('some_method', 'param');
      final DaemonMessage message = await daemonStreams.outputs.stream.first;

      expect(message.data['id'], isNotNull);
      expect(message.data['method'], 'some_method');
      expect(message.data['params'], 'param');

      final String id = message.data['id']! as String;
      daemonStreams.inputs.add(DaemonMessage(<String, dynamic>{'id': id, 'error': 'some_error', 'trace': 'stack trace'}));

      Object? gotError;
      StackTrace? gotStackTrace;
      try {
        await requestFuture;
      } on Object catch (error, stackTrace) {
        gotError = error;
        gotStackTrace = stackTrace;
      }

      expect(gotError, 'some_error');
      expect(gotStackTrace.toString(), 'stack trace');
    });
  });

  group('DaemonInputStreamConverter', () {
    Map<String, Object?> testCommand(int id, [int? binarySize]) => <String, Object?>{
      'id': id,
      'method': 'test',
      if (binarySize != null)
        '_binaryLength': binarySize,
    };
    List<int> testCommandBinary(int id, [int? binarySize]) => utf8.encode('[${json.encode(testCommand(id, binarySize))}]\n');

    testWithoutContext('can parse a single message', () async {
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10),
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<DaemonMessage> outputs = await outputStream.toList();
      expect(outputs, hasLength(1));
      expect(outputs[0].data, testCommand(10));
      expect(outputs[0].binary, null);
    });

    testWithoutContext('can parse multiple messages', () async {
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10),
        testCommandBinary(20),
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<DaemonMessage> outputs = await outputStream.toList();
      expect(outputs, hasLength(2));
      expect(outputs[0].data, testCommand(10));
      expect(outputs[0].binary, null);
      expect(outputs[1].data, testCommand(20));
      expect(outputs[1].binary, null);
    });

    testWithoutContext('can parse multiple messages while ignoring non json data in between', () async {
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10),
        utf8.encode('This is not a json data...\n'),
        testCommandBinary(20),
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<DaemonMessage> outputs = await outputStream.toList();
      expect(outputs, hasLength(2));
      expect(outputs[0].data, testCommand(10));
      expect(outputs[0].binary, null);
      expect(outputs[1].data, testCommand(20));
      expect(outputs[1].binary, null);
    });

    testWithoutContext('can parse multiple messages even when they are split in multiple packets', () async {
      final List<int> binary1 = testCommandBinary(10);
      final List<int> binary2 = testCommandBinary(20);
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        binary1.sublist(0, 5),
        binary1.sublist(5, 15),
        binary1.sublist(15) + binary2.sublist(0, 13),
        binary2.sublist(13),
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<DaemonMessage> outputs = await outputStream.toList();
      expect(outputs, hasLength(2));
      expect(outputs[0].data, testCommand(10));
      expect(outputs[0].binary, null);
      expect(outputs[1].data, testCommand(20));
      expect(outputs[1].binary, null);
    });

    testWithoutContext('can parse multiple messages even when they are combined in a single packet', () async {
      final List<int> binary1 = testCommandBinary(10);
      final List<int> binary2 = testCommandBinary(20);
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        binary1 + binary2,
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<DaemonMessage> outputs = await outputStream.toList();
      expect(outputs, hasLength(2));
      expect(outputs[0].data, testCommand(10));
      expect(outputs[0].binary, null);
      expect(outputs[1].data, testCommand(20));
      expect(outputs[1].binary, null);
    });

    testWithoutContext('can parse a single message with binary stream', () async {
      final List<int> binary = <int>[1,2,3,4,5];
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10, binary.length),
        binary,
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<_DaemonMessageAndBinary> allOutputs = await _readAllBinaries(outputStream);
      expect(allOutputs, hasLength(1));
      expect(allOutputs[0].message.data, testCommand(10, binary.length));
      expect(allOutputs[0].binary, binary);
    });

    testWithoutContext('can parse a single message with binary stream when messages are combined in a single packet', () async {
      final List<int> binary = <int>[1,2,3,4,5];
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10, binary.length) + binary,
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<_DaemonMessageAndBinary> allOutputs = await _readAllBinaries(outputStream);
      expect(allOutputs, hasLength(1));
      expect(allOutputs[0].message.data, testCommand(10, binary.length));
      expect(allOutputs[0].binary, binary);
    });

    testWithoutContext('can parse multiple messages with binary stream', () async {
      final List<int> binary1 = <int>[1,2,3,4,5];
      final List<int> binary2 = <int>[6,7,8,9,10,11,12];
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        testCommandBinary(10, binary1.length),
        binary1,
        testCommandBinary(20, binary2.length),
        binary2,
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<_DaemonMessageAndBinary> allOutputs = await _readAllBinaries(outputStream);
      expect(allOutputs, hasLength(2));
      expect(allOutputs[0].message.data, testCommand(10, binary1.length));
      expect(allOutputs[0].binary, binary1);
      expect(allOutputs[1].message.data, testCommand(20, binary2.length));
      expect(allOutputs[1].binary, binary2);
    });

    testWithoutContext('can parse multiple messages with binary stream when messages are split', () async {
      final List<int> binary1 = <int>[1,2,3,4,5];
      final List<int> message1 = testCommandBinary(10, binary1.length);
      final List<int> binary2 = <int>[6,7,8,9,10,11,12];
      final List<int> message2 = testCommandBinary(20, binary2.length);
      final Stream<List<int>> inputStream = Stream<List<int>>.fromIterable(<List<int>>[
        message1.sublist(0, 10),
        message1.sublist(10) + binary1 + message2.sublist(0, 5),
        message2.sublist(5) + binary2.sublist(0, 3),
        binary2.sublist(3, 5),
        binary2.sublist(5),
      ]);
      final DaemonInputStreamConverter converter = DaemonInputStreamConverter(inputStream);
      final Stream<DaemonMessage> outputStream = converter.convertedStream;
      final List<_DaemonMessageAndBinary> allOutputs = await _readAllBinaries(outputStream);
      expect(allOutputs, hasLength(2));
      expect(allOutputs[0].message.data, testCommand(10, binary1.length));
      expect(allOutputs[0].binary, binary1);
      expect(allOutputs[1].message.data, testCommand(20, binary2.length));
      expect(allOutputs[1].binary, binary2);
    });
  });

  group('DaemonStreams', () {
    final Map<String, Object?> testCommand = <String, Object?>{
      'id': 100,
      'method': 'test',
    };
    late StreamController<List<int>> inputStream;
    late StreamController<List<int>> outputStream;
    late DaemonStreams daemonStreams;
    setUp(() {
      inputStream = StreamController<List<int>>();
      outputStream = StreamController<List<int>>();
      daemonStreams = DaemonStreams(inputStream.stream, outputStream.sink, logger: bufferLogger);
    });

    testWithoutContext('parses the message received on the stream', () async {
      inputStream.add(utf8.encode('[${jsonEncode(testCommand)}]\n'));
      final DaemonMessage command = await daemonStreams.inputStream.first;
      expect(command.data, testCommand);
      expect(command.binary, null);
    });

    testWithoutContext('sends the encoded message through the sink', () async {
      daemonStreams.send(testCommand);
      final List<int> commands = await outputStream.stream.first;
      expect(commands, utf8.encode('[${jsonEncode(testCommand)}]\n'));
    });

    testWithoutContext('dispose closes the sink', () async {
      await daemonStreams.dispose();
      expect(outputStream.isClosed, true);
    });

    testWithoutContext('handles sending to a closed sink', () async {
      // Unless the stream is listened to, the call to .close() will never
      // complete
      outputStream.stream.listen((List<int> _) {});
      await outputStream.sink.close();
      daemonStreams.send(testCommand);
      expect(
        bufferLogger.errorText,
        contains(
          'Failed to write daemon command response: Bad state: Cannot add event after closing',
        ),
      );
    });
  });
}

class _DaemonMessageAndBinary {
  _DaemonMessageAndBinary(this.message, this.binary);
  final DaemonMessage message;
  final List<int>? binary;
}

Future<List<_DaemonMessageAndBinary>> _readAllBinaries(Stream<DaemonMessage> inputStream) async {
  final StreamIterator<DaemonMessage> iterator = StreamIterator<DaemonMessage>(inputStream);
  final List<_DaemonMessageAndBinary> outputs = <_DaemonMessageAndBinary>[];
  while (await iterator.moveNext()) {
    List<int>? binary;
    if (iterator.current.binary != null) {
      binary = await iterator.current.binary!.reduce((List<int> a, List<int> b) => a + b);
    }
    outputs.add(_DaemonMessageAndBinary(iterator.current, binary));
  }
  return outputs;
}
