// Copyright (c) 2018, 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.

/// @assertion Stream<S> expand<S>(Iterable<S> convert(T value))
/// Transforms each element of this stream into a sequence of elements.
///
/// Returns a new stream where each element of this stream is replaced by zero or
/// more data events. The event values are provided as an Iterable by a call to
/// convert with the element as argument, and the elements of that iterable is
/// emitted in iteration order.
///
/// @description Checks that method [expand] returns a new stream where each
/// element of this stream is replaced by zero or more data events.
/// @author ngl@unipro.ru

import "dart:async";
import "dart:io";
import "../http_utils.dart";
import "../../../Utils/expect.dart";

var localhost = InternetAddress.loopbackIPv4;

Future<List> checkExpand(convert) async {
  RawDatagramSocket producer = await RawDatagramSocket.bind(localhost, 0);
  RawDatagramSocket receiver = await RawDatagramSocket.bind(localhost, 0);
  List<List<int>> toSend = [[0, 1, 2, 3], [1, 2, 3], [2, 3], [3]];
  Completer<List> completer = new Completer<List>();
  Future<List> f = completer.future;
  List received = [];

  bool wasSent = await sendDatagram(producer, toSend, localhost, receiver.port);
  Expect.isTrue(wasSent, "No datagram was sent");
  receiver.close();

  Stream s = receiver.expand(convert);
  s.listen((value) {
    received.add(value);
  }).onDone(() {
    if (!completer.isCompleted) {
      completer.complete(received);
    }
  });

  return f;
}

main() async {
  int attempts = 5;

  toCheck(convert, List expected, int newReplaced) async {
    for (int i = 0; i < attempts; i++) {
      List list = await checkExpand(convert);
      int recLength = list.length;

      if (recLength == newReplaced && recLength == 0) {
        break;
      }
      bool notFound = false;
      if (recLength > 0 || recLength >= newReplaced) {
        if (newReplaced == 1) {
          for (int i = 0; i < list.length; i++) {
            if (list[i] != expected[0] && list[i] != expected[1] &&
                list[i] != expected[2]) {
              notFound = true;
              break;
            }
          }
          if (!notFound) {
            break;
          }
        }
        if (newReplaced == 2) {
          for (int i = 0; i < list.length; i++) {
            if (list[i] != expected[0] && list[i] != expected[1] &&
                list[i] != expected[2]) {
              notFound = true;
              break;
            }
            if (i + 1 >= recLength ) {
              notFound = true;
              break;
            }
            if (list[i + 1] != list[i]) {
              notFound = true;
              break;
            }
            i++;
          }
          if (!notFound) {
            break;
          }
        }
        if (newReplaced == 3) {
          for (int i = 0; i < list.length; i+=3) {
            if (i + 1 >= recLength && i + 2 >= recLength) {
              notFound = true;
              break;
            }
            if (list[i] != expected[0] || list[i + 1] != expected[1] ||
                list[i + 2] != expected[2]) {
              notFound = true;
              break;
            }
          }

          if (!notFound) {
            break;
          }
        }
      }

      if (i == attempts - 1) {
        print('$recLength elements not found. Look like test failed.');
      }
    }
  }

  await toCheck((e) => [], [], 0);
  await toCheck((e) => [e], [RawSocketEvent.closed], 1);
  await toCheck((e) => [e, e], [RawSocketEvent.closed], 2);
  await toCheck((e) => [1, 2, 3], [1, 2, 3], 3);
}
