/*
 * Copyright (c) 2017, 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.
 */
/*
 * http and web sockets utils
 * @author a.semenov@unipro.ru
 */
library http_utils;

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

/**
 * Spawns a HttpServer instance
 */
Future<HttpServer> spawnHttpServer(void requestHandler(HttpRequest request)) async {
  HttpServer server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
  server.listen(requestHandler);
  return server;
}

/**
 * Spawns a HttpServer instance that is intended to handle web sockets.
 */
Future<HttpServer> spawnWebSocketServer(void wsHandler(WebSocket webSocket)) {
  return spawnHttpServer((HttpRequest request) {
    WebSocketTransformer.upgrade(request).then(wsHandler);
  });
}

/**
 * Spawns a HttpServer instance that is intended to handle web sockets.
 * Each new connection receives the same [content] and then closed.
 */
Future<HttpServer> spawnStaticContentWebSocketServer(content) {
  return spawnWebSocketServer((WebSocket webSocket) {
    webSocket.add(content);
    webSocket.close();
  });
}

/**
 * Spawns a HttpServer instance that is intended to handle web sockets.
 * Each new connection is listened for first message and send it back,
 * then web socket is closed.
 */
Future<HttpServer> spawnEchoWebSocketServer() {
  return spawnWebSocketServer((WebSocket webSocket) async {
    webSocket.add(await webSocket.first);
    webSocket.close();
  });
}

List<int> _bigData = [];

List<int> get bigData  {
 if (_bigData.isEmpty) {
   _bigData = getList(8187);
 }
 return _bigData;
}

List<int> getList(int size) {
  List<int> l = [];
  for (int j = 0; j < size; j++) {
    l.add(j);
  }
  return l;
}

Future<List<int>> sendDatagramOnce(RawDatagramSocket producer,
    List<List<int>> data, InternetAddress address, int port,
    {Duration period = const Duration(milliseconds: 1)}) {
  List<int> sent = [];
  Completer<List<int>> completer = new Completer<List<int>>();
  Future<List<int>> f = completer.future;
  int i = 0;
  new Timer.periodic(period, (timer) {
    if (i < data.length) {
      sent.add(producer.send(data[i++], address, port));
    } else {
      timer.cancel();
      completer.complete(sent);
    }
  });
  return f;
}

Future<bool> sendDatagram(RawDatagramSocket producer, List<List<int>> data,
    InternetAddress address, int port,
    {Duration period = const Duration(milliseconds: 1), int attempts = 5,
      bool closeProducer = true}) async {
  for (int attempt = 0; attempt < attempts; attempt++) {
    List<int> bytesWritten = await sendDatagramOnce(producer, data, address, port,
        period: period);
    if (wasSent(bytesWritten)) {
      compareSentData(data, bytesWritten);
      if (closeProducer) {
        producer.close();
      }
      return true;
    }
  }
  producer.close();
  return false;
}

/***
 * Check that there is any buffer size > 0
 */
bool wasSent(List<int> bytesWritten) {
  for (int i = 0; i < bytesWritten.length; i++) {
    if (bytesWritten[i] > 0) {
      return true;
    }
  }
  return false;
}

compareSentData(List<List<int>> data, List<int> sentStatus) {
  Expect.equals(sentStatus.length, data.length, "Wrong sizes of sent and sentResult");
  for (int i = 0; i < data.length; i++) {
    if (sentStatus[i] == 0) {
      continue;
    }
    Expect.equals(data[i].length, sentStatus[i]);
  }
}

Future<List<List<int>>> receiveDatagram(RawDatagramSocket receiver,
    {Duration delay = const Duration(seconds: 2), RawSocketEvent? event}) {
  List<List<int>> received = [];
  Completer<List<List<int>>> completer = new Completer<List<List<int>>>();
  Future<List<List<int>>> f = completer.future;
  receiver.listen((_event) {
    var datagram = receiver.receive();
    if (event == null || _event == event) {
      var d = datagram?.data.toList();
      if (d != null) {
        received.add(d);
      }
    }
    if (_event == RawSocketEvent.closed) {
      if(!completer.isCompleted) {
        completer.complete(received);
      }
    }
  });
  new Future.delayed(delay, () {
    if(!completer.isCompleted) {
      receiver.close();
      completer.complete(received);
    }
  });
  return f;
}

/**
 * If we receive datagram we check if received data can be found among sent ones
 */
compareReceivedData(List<List<int>> sent, List<List<int>> received) {
  Expect.isTrue(received.length <= sent.length, "${received.length} <= ${sent.length}");
  for (int i = 0; i < received.length; i++) {
    bool found = false;
    for (int j = 0; j < sent.length; j++) {
      if (_listEquals(received[i], sent[j])) {
        found = true;
        break;
      }
    }
    Expect.isTrue(found, "${received[i]} not found among $sent");
  }
}

bool _listEquals(List<int> list1, List<int> list2) {
  if (list1.length == list2.length) {
    for (int i = 0; i < list1.length; i++) {
      if (list1[i] != list2[i]) {
        return false;
      }
    }
    return true;
  }
  return false;
}

Future<List<RawSocketEvent>> anyElement(RawDatagramSocket receiver,
    RawSocketEvent expectedEvent, bool shouldFind,
    {Duration delay = const Duration(seconds: 2)}) {
  List<RawSocketEvent> tested = [];
  Completer<List<RawSocketEvent>> completer =
      new Completer<List<RawSocketEvent>>();
  Future<List<RawSocketEvent>> f = completer.future;

  bool test(x) {
    tested.add(x);
    receiver.receive();
    if (x == RawSocketEvent.closed) {
      if (!completer.isCompleted) {
        completer.complete(tested);
      }
    }
    return x == expectedEvent;
  }

  receiver.any((event) => test(event)).then((value) {
    if (shouldFind) {
      Expect.equals(true, value);
    } else {
      Expect.equals(false, value);
    }
    if (!completer.isCompleted) {
      receiver.close();
      completer.complete(tested);
    }
  });

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

checkTested<T>(List<T> tested, T expected) {
  for (int i = tested.length - 2; i >= 0; i--) {
    Expect.notEquals(expected, tested[i]);
  }
}

checkReceived(check, List<RawSocketEvent> expectedValues, int expectedLen,
    {int attempts = 5}) async {
  for (int i = 0; i < attempts; i++) {
    List list = await check();
    int listLen = list.length;
    if (listLen == 0) {
      continue;
    }
    if (listLen > 0 && listLen <= expectedLen) {
      for (int i = 0; i < list.length; i++) {
        Expect.isTrue(
            expectedValues.contains(list[i]), "Unexpected value ${list[i]}");
      }
      break;
    }
    if (listLen > expectedLen) {
      Expect.fail("$listLen elements found instead of $expectedLen.");
    }
    if (i == attempts - 1) {
      print('$listLen elements found. Look like test failed.');
    }
  }
}
