// 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))
/// . . .
/// If calling convert throws, or if the iteration of the returned values throws,
/// the error is emitted on the returned stream and iteration ends for that
/// element of this stream.
///
/// @description Checks that if calling convert throws, the error is emitted on
/// the returned stream and iteration ends for that element of this stream.
/// @author ngl@unipro.ru

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

var localhost = InternetAddress.loopbackIPv4;

Future<List<dynamic>> checkExpend(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]];
  Completer<List<dynamic>> completer = new Completer<List<dynamic>>();
  Future<List<dynamic>> f = completer.future;
  Duration delay = const Duration(seconds: 2);
  List<dynamic> received = [];
  List<RawSocketEvent> receivedEvents = [];

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

  Stream<RawSocketEvent> bcs = receiver.asBroadcastStream();
  Stream<dynamic> s = bcs.expand(convert);

  s.listen((event) {
    received.add(event);
  }, onError: (error) {
    received.add(error);
  }, onDone: () {
    if (!completer.isCompleted) {
      completer.complete(received);
    }
  });

  bcs.listen((event) {
    receivedEvents.add(event);
    receiver.receive();
  }).onDone(() {
    if (!completer.isCompleted) {
      completer.complete(received);
    }
  });

  new Future.delayed(delay, () {
    if (!completer.isCompleted) {
      receiver.close();
    }
  });

  return f;
}

main() async {
  int attempts = 5;
  bool errorFound = false;

  toCheck(convert, int newError) async {
    for (int i = 0; i < attempts; i++) {
      List<dynamic> list = await checkExpend(convert);
      int receivedLength = list.length;

      errorFound = true;
      for (int i = 0; i < receivedLength; i++) {
        if (list[i] == newError) {
          errorFound = false;
          break;
        }
      }
      if (!errorFound) {
        break;
      }

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

  await toCheck((e) => e == RawSocketEvent.write ? throw 11 : [e], 11);
  await toCheck((e) => e == RawSocketEvent.read ? throw 12 : [e], 12);
  await toCheck((e) => e == RawSocketEvent.closed ? throw 13 : [e], 13);

  await toCheck((e) => e == RawSocketEvent.write ? throw 11 : [1, 2, 3], 11);
  await toCheck((e) => e == RawSocketEvent.read ? throw 12 : [1, 2, 3], 12);
  await toCheck((e) => e == RawSocketEvent.closed ? throw 13 : [1, 2, 3], 13);
}
