// 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.

// @dart = 2.9

/// @assertion Future<RawSecureSocket> single
/// The single element of this stream.
///
/// @description Checks that [single] returns the future that completes with
/// the single element of this socket.
/// @author ngl@unipro.ru

// OtherResources=server_chain.pem
// OtherResources=server_key.pem
// OtherResources=trusted_certs.pem
import "dart:io";
import "dart:async";
import "../../../Utils/expect.dart";

String localFile(path) => Platform.script.resolve(path).toFilePath();

SecurityContext serverContext = new SecurityContext()
  ..useCertificateChain(localFile('server_chain.pem'))
  ..usePrivateKey(localFile('server_key.pem'),
      password: 'co19test');

SecurityContext clientContext = new SecurityContext()
  ..setTrustedCertificates(localFile('trusted_certs.pem'));

check(InternetAddress address) {
  const messageSize = 10;
  List<int> expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  List<RawSecureSocket> sList = [null, null];
  int sli = 0;
  var closed = 0;
  asyncStart();
  RawSecureServerSocket.bind(address, 0, serverContext).then((server) {
    Stream<RawSecureSocket> bs = server.asBroadcastStream();
    bs.single.then((value) {
      Expect.equals(sList[0], value);
      asyncEnd();
    });

    bs.listen((client) {
      int bytesRead = 0;
      int bytesWritten = 0;
      List<int> data = new List<int>.filled(messageSize, 0);
      client.writeEventsEnabled = false;
      sList[sli++] = client;
      client.listen((event) {
        switch (event) {
          case RawSocketEvent.read:
            Expect.isTrue(client.available() > 0);
            var buffer = client.read();
            if (buffer != null) {
              data.setRange(bytesRead, bytesRead + buffer.length, buffer);
              bytesRead += buffer.length;
              Expect.listEquals(expected, buffer);
            }
            if (bytesRead == data.length) {
              Expect.listEquals(expected, data);
              client.writeEventsEnabled = true;
            }
            break;
          case RawSocketEvent.write:
            Expect.listEquals(expected, data);
            bytesWritten +=
                client.write(data, bytesWritten, data.length - bytesWritten);
            if (bytesWritten < data.length) {
              client.writeEventsEnabled = true;
            }
            if (bytesWritten == data.length) {
              client.shutdown(SocketDirection.send);
            }
            break;
          case RawSocketEvent.readClosed:
            closed++;
            break;
          default:
            throw "Unexpected event $event";
        }
      }).onDone(() {
        if (closed == 1) {
          server.close();
        }
      });
    });

    RawSocket.connect(server.address, server.port).then((socket) {
      RawSecureSocket.secure(socket, context: clientContext).then((client) {
        var completer = new Completer();
        int bytesRead = 0;
        int bytesWritten = 0;
        List<int> dataSent = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
        List<int> dataReceived = new List<int>.filled(dataSent.length, 0);
        client.listen((event) {
          switch (event) {
            case RawSocketEvent.read:
              Expect.isTrue(client.available() > 0);
              var buffer = client.read();
              if (buffer != null) {
                dataReceived.setRange(
                    bytesRead, bytesRead + buffer.length, buffer);
                bytesRead += buffer.length;
              }
              break;
            case RawSocketEvent.write:
              Expect.isTrue(bytesRead == 0);
              bytesWritten += client.write(
                  dataSent, bytesWritten, dataSent.length - bytesWritten);
              if (bytesWritten < dataSent.length) {}
              break;
            case RawSocketEvent.readClosed:
              Expect.listEquals(expected, dataReceived);
              completer.complete(client);
              break;
            default:
              throw "Unexpected event $event";
          }
        });
        completer.future.then((_) {
          socket.close();
        });
      });
    });
  });
}

main() {
  check(InternetAddress.loopbackIPv4);
  check(InternetAddress.loopbackIPv6);
}
