// Copyright (c) 2015, 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:http2/src/flowcontrol/window.dart';
import 'package:http2/src/flowcontrol/window_handler.dart';
import 'package:http2/src/frames/frames.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../error_matchers.dart';

void main() {
  group('flowcontrol', () {
    void testAbstractOutgoingWindowHandler(
      AbstractOutgoingWindowHandler handler,
      Window window,
      int initialSize,
    ) {
      var sub = handler.positiveWindow.bufferEmptyEvents.listen(
        expectAsync1((_) {}, count: 0),
      );

      expect(handler.peerWindowSize, initialSize);
      expect(window.size, initialSize);

      // If we're sending data to the remote end, we need to subtract
      // the number of bytes from the outgoing connection (and stream) windows.
      handler.decreaseWindow(100);
      expect(handler.peerWindowSize, initialSize - 100);
      expect(window.size, initialSize - 100);

      // If we received a window update frame, the window should be increased
      // again.
      var frameHeader = FrameHeader(4, FrameType.WINDOW_UPDATE, 0, 0);
      handler.processWindowUpdate(WindowUpdateFrame(frameHeader, 100));
      expect(handler.peerWindowSize, initialSize);
      expect(window.size, initialSize);

      sub.cancel();

      // If we decrease the outgoing window size to 0 or below, and
      // increase it again, we expect to get an update event.
      expect(handler.positiveWindow.wouldBuffer, isFalse);
      handler.decreaseWindow(window.size);
      expect(handler.positiveWindow.wouldBuffer, isTrue);
      sub = handler.positiveWindow.bufferEmptyEvents.listen(
        expectAsync1((_) {
          expect(handler.peerWindowSize, 1);
          expect(window.size, 1);
        }),
      );

      // Now we trigger the 1 byte window increase
      handler.processWindowUpdate(WindowUpdateFrame(frameHeader, 1));
      sub.cancel();

      // If the remote end sends us [WindowUpdateFrame]s which increase it above
      // the maximum size, we throw a [FlowControlException].
      var frame = WindowUpdateFrame(frameHeader, Window.MAX_WINDOW_SIZE);
      expect(
        () => handler.processWindowUpdate(frame),
        throwsA(isFlowControlException),
      );
    }

    test('outgoing-connection-window-handler', () {
      var window = Window();
      var initialSize = window.size;
      var handler = OutgoingConnectionWindowHandler(window);

      testAbstractOutgoingWindowHandler(handler, window, initialSize);
    });

    test('outgoing-stream-window-handler', () {
      var window = Window();
      var initialSize = window.size;
      var handler = OutgoingStreamWindowHandler(window);

      testAbstractOutgoingWindowHandler(handler, window, initialSize);

      // Test stream specific functionality: If the connection window
      // gets increased/decreased via a [SettingsFrame], all stream
      // windows need to get updated as well.

      window = Window();
      initialSize = window.size;
      handler = OutgoingStreamWindowHandler(window);

      expect(handler.positiveWindow.wouldBuffer, isFalse);
      final bufferEmpty = handler.positiveWindow.bufferEmptyEvents.listen(
        expectAsync1((_) {}, count: 0),
      );
      handler.processInitialWindowSizeSettingChange(-window.size);
      expect(handler.positiveWindow.wouldBuffer, isTrue);
      expect(handler.peerWindowSize, 0);
      expect(window.size, 0);
      bufferEmpty.onData(expectAsync1((_) {}, count: 1));
      handler.processInitialWindowSizeSettingChange(1);
      expect(handler.positiveWindow.wouldBuffer, isFalse);
      expect(handler.peerWindowSize, 1);
      expect(window.size, 1);

      expect(
        () => handler.processInitialWindowSizeSettingChange(
          Window.MAX_WINDOW_SIZE + 1,
        ),
        throwsA(isFlowControlException),
      );
    });

    test('incoming-window-handler', () {
      const STREAM_ID = 99;

      var fw = FrameWriterMock();
      var window = Window();
      var initialSize = window.size;
      var handler = IncomingWindowHandler.stream(fw, window, STREAM_ID);

      expect(handler.localWindowSize, initialSize);
      expect(window.size, initialSize);

      // If the remote end sends us now 100 bytes, it reduces the local
      // incoming window by 100 bytes. Once we handled these bytes, it,
      // will send a [WindowUpdateFrame] to the remote peer to ACK it.
      handler.gotData(100);
      expect(handler.localWindowSize, initialSize - 100);
      expect(window.size, initialSize - 100);

      // The data might sit in a queue. Once the user drains enough data of
      // the queue, we will start ACKing the data and the window becomes
      // positive again.
      handler.dataProcessed(100);
      expect(handler.localWindowSize, initialSize);
      expect(window.size, initialSize);
      verify(fw.writeWindowUpdate(100, streamId: STREAM_ID)).called(1);
      verifyNoMoreInteractions(fw);
    });
  });
}

class FrameWriterMock extends Mock implements FrameWriter {}
