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

import 'package:http2/transport.dart';
import 'package:test/test.dart';

import 'helper.dart';

void main() {
  group('streams', () {
    group('flowcontrol', () {
      const numOfOneKB = 1000;

      var expectedHeaders = [Header.ascii('key', 'value')];
      var allBytes = List.generate(numOfOneKB * 1024, (i) => i % 256);
      allBytes.addAll(List.generate(42, (i) => 42));

      void Function(StreamMessage) headersTestFun(String type) {
        return expectAsync1((StreamMessage msg) {
          expect(
            msg,
            isA<HeadersStreamMessage>()
                .having(
                  (m) => m.headers.first.name,
                  'headers.first.name',
                  expectedHeaders.first.name,
                )
                .having(
                  (m) => m.headers.first.value,
                  'headers.first.value',
                  expectedHeaders.first.value,
                ),
          );
        });
      }

      var serverReceivedAllBytes = Completer<void>();

      void Function(StreamMessage) messageTestFun(String type) {
        var expectHeader = true;
        var numBytesReceived = 0;
        return (StreamMessage msg) {
          if (expectHeader) {
            expectHeader = false;
            expect(
              msg,
              isA<HeadersStreamMessage>()
                  .having(
                    (m) => m.headers.first.name,
                    'headers.first.name',
                    expectedHeaders.first.name,
                  )
                  .having(
                    (m) => m.headers.first.value,
                    'headers.first.value',
                    expectedHeaders.first.value,
                  ),
            );
          } else {
            expect(msg, isA<DataStreamMessage>());
            var bytes = (msg as DataStreamMessage).bytes;
            expect(
              bytes,
              allBytes.sublist(
                numBytesReceived,
                numBytesReceived + bytes.length,
              ),
            );
            numBytesReceived += bytes.length;

            if (numBytesReceived > allBytes.length) {
              if (serverReceivedAllBytes.isCompleted) {
                throw Exception('Got more messages than expected');
              }
              serverReceivedAllBytes.complete();
            }
          }
        };
      }

      void sendData(TransportStream cStream) {
        for (var i = 0; i < (allBytes.length + 1023) ~/ 1024; i++) {
          var end = 1024 * (i + 1);
          var isLast = end > allBytes.length;
          if (isLast) {
            end = allBytes.length;
          }
          cStream.sendData(allBytes.sublist(1024 * i, end), endStream: isLast);
        }
      }

      streamTest('single-header-request--empty-response', (
        ClientTransportConnection client,
        ServerTransportConnection server,
      ) async {
        server.incomingStreams.listen(
          expectAsync1((TransportStream sStream) async {
            sStream.incomingMessages.listen(
              messageTestFun('server'),
              onDone: expectAsync0(() {}),
            );
            sStream.sendHeaders(expectedHeaders, endStream: true);
            await serverReceivedAllBytes.future;
          }),
        );

        TransportStream cStream = client.makeRequest(expectedHeaders);
        sendData(cStream);
        cStream.incomingMessages.listen(
          headersTestFun('client'),
          onDone: expectAsync0(() {}),
        );
      });
    });
  });
}
