// 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 'dart:typed_data';

import 'package:fake_async/fake_async.dart';
import 'package:flutter_tools/src/proxied_devices/debounce_data_stream.dart';

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

void main() {
  group('debounceDataStreams', () {
    late FakeAsync fakeAsync;
    late StreamController<Uint8List> source;
    late Stream<Uint8List> output;
    const Duration debounceDuration = Duration(seconds: 10);
    const Duration smallDuration = Duration(milliseconds: 10);

    void addToSource(int value) {
      source.add(Uint8List.fromList(<int>[value]));
    }

    setUp(() {
      fakeAsync = FakeAsync();
      fakeAsync.run((FakeAsync time) {
        source = StreamController<Uint8List>();
        output = debounceDataStream(source.stream, debounceDuration);
      });
    });

    testWithoutContext('does not listen if returned stream is not listened to', () {
      expect(source.hasListener, false);
      output.listen(dummy);
      expect(source.hasListener, true);
    });

    testWithoutContext('forwards data normally is all data if longer than duration apart', () {
      fakeAsync.run((FakeAsync time) {
        final List<Uint8List> outputItems = <Uint8List>[];
        output.listen(outputItems.add);

        addToSource(1);
        time.elapse(debounceDuration + smallDuration);
        addToSource(2);
        time.elapse(debounceDuration + smallDuration);
        addToSource(3);
        time.elapse(debounceDuration + smallDuration);

        expect(outputItems, <List<int>>[
          <int>[1],
          <int>[2],
          <int>[3],
        ]);
      });
    });

    testWithoutContext('merge data after the first if sent within duration', () {
      fakeAsync.run((FakeAsync time) {
        final List<Uint8List> outputItems = <Uint8List>[];
        output.listen(outputItems.add);

        addToSource(1);
        time.elapse(smallDuration);
        addToSource(2);
        time.elapse(smallDuration);
        addToSource(3);
        time.elapse(debounceDuration + smallDuration);

        expect(outputItems, <List<int>>[
          <int>[1],
          <int>[2, 3],
        ]);
      });
    });

    testWithoutContext('output data in separate chunks if time between them is longer than duration', () {
      fakeAsync.run((FakeAsync time) {
        final List<Uint8List> outputItems = <Uint8List>[];
        output.listen(outputItems.add);

        addToSource(1);
        time.elapse(smallDuration);
        addToSource(2);
        time.elapse(smallDuration);
        addToSource(3);
        time.elapse(debounceDuration + smallDuration);
        addToSource(4);
        time.elapse(smallDuration);
        addToSource(5);
        time.elapse(debounceDuration + smallDuration);

        expect(outputItems, <List<int>>[
          <int>[1],
          <int>[2, 3],
          <int>[4, 5],
        ]);
      });
    });

    testWithoutContext('sends the last chunk after debounce duration', () {
      fakeAsync.run((FakeAsync time) {
        final List<Uint8List> outputItems = <Uint8List>[];
        output.listen(outputItems.add);

        addToSource(1);
        time.flushMicrotasks();
        expect(outputItems, <List<int>>[<int>[1]]);

        time.elapse(smallDuration);
        addToSource(2);
        time.elapse(smallDuration);
        addToSource(3);
        expect(outputItems, <List<int>>[<int>[1]]);

        time.elapse(debounceDuration + smallDuration);
        expect(outputItems, <List<int>>[
          <int>[1],
          <int>[2, 3],
        ]);
      });
    });

    testWithoutContext('close if source stream is closed', () {
      fakeAsync.run((FakeAsync time) {
        bool isDone = false;
        output.listen(dummy, onDone: () => isDone = true);
        expect(isDone, false);
        source.close();
        time.flushMicrotasks();
        expect(isDone, true);
      });
    });

    testWithoutContext('delay close until after last chunk is sent', () {
      fakeAsync.run((FakeAsync time) {
        final List<Uint8List> outputItems = <Uint8List>[];
        bool isDone = false;
        output.listen(outputItems.add, onDone: () => isDone = true);

        addToSource(1);
        time.flushMicrotasks();
        expect(outputItems, <List<int>>[<int>[1]]);

        addToSource(2);
        source.close();
        time.elapse(smallDuration);
        expect(isDone, false);
        expect(outputItems, <List<int>>[<int>[1]]);

        time.elapse(debounceDuration + smallDuration);
        expect(outputItems, <List<int>>[
          <int>[1],
          <int>[2],
        ]);
        expect(isDone, true);
      });
    });

    testWithoutContext('close if returned stream is closed', () {
      fakeAsync.run((FakeAsync time) {
        bool isCancelled = false;
        source.onCancel = () => isCancelled = true;
        final StreamSubscription<Uint8List> subscription = output.listen(dummy);
        expect(isCancelled, false);
        subscription.cancel();
        expect(isCancelled, true);
      });
    });
  });
}

Uint8List dummy(Uint8List data) => data;
