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

// VMOptions=--enable-isolate-groups
// VMOptions=--no-enable-isolate-groups
//
// Echo server test program to test socket streams.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

library ServerTest;

import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
import "dart:async";
import "dart:io";
import "dart:isolate";
part "testing_server.dart";

class EchoServerGame {
  static const MSGSIZE = 10;
  static const MESSAGES = 100;
  static const FIRSTCHAR = 65;

  EchoServerGame.start() {
    for (int i = 0; i < MSGSIZE; i++) {
      _buffer[i] = FIRSTCHAR + i;
    }
    initialize();
  }

  void sendData() {
    int offset = 0;
    List<int> data;

    void onData(List<int> data) {
      int bytesRead = data.length;
      for (int i = 0; i < data.length; i++) {
        Expect.equals(FIRSTCHAR + i + offset, data[i]);
      }
      offset += bytesRead;
    }

    void onClosed() {
      Expect.equals(MSGSIZE, offset);
      _messages++;
      if (_messages < MESSAGES) {
        sendData();
      } else {
        shutdown();
      }
    }

    void errorHandler(e, trace) {
      String msg = "Socket error $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    }

    void connectHandler() {
      _socket.listen(onData, onError: errorHandler, onDone: onClosed);
      _socket.add(_buffer);
      _socket.close();
      data = new List<int>.filled(MSGSIZE, 0);
    }

    Socket.connect(TestingServer.HOST, _port).then((s) {
      _socket = s;
      connectHandler();
    });
  }

  void initialize() {
    var receivePort = new ReceivePort();
    var remote = Isolate.spawn(startEchoServer, receivePort.sendPort);
    receivePort.first.then((msg) {
      this._port = msg[0];
      this._closeSendPort = msg[1];
      sendData();
    });
  }

  void shutdown() {
    _closeSendPort.send(null);
    asyncEnd();
  }

  late int _port;
  late SendPort _closeSendPort;
  late Socket _socket;
  final _buffer = new List<int>.filled(MSGSIZE, 0);
  int _messages = 0;
}

void startEchoServer(Object replyPortObj) {
  SendPort replyPort = replyPortObj as SendPort;
  var server = new EchoServer();
  server.init().then((port) {
    replyPort.send([port, server.closeSendPort]);
  });
}

class EchoServer extends TestingServer {
  static const int MSGSIZE = EchoServerGame.MSGSIZE;

  void onConnection(Socket connection) {
    List<int> buffer = new List<int>.filled(MSGSIZE, 0);
    int offset = 0;

    void dataReceived(List<int> data) {
      int bytesRead;
      bytesRead = data.length;
      if (bytesRead > 0) {
        buffer.setRange(offset, offset + data.length, data);
        offset += bytesRead;
        for (int i = 0; i < offset; i++) {
          Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
        }
        if (offset == MSGSIZE) {
          connection.add(buffer);
          connection.close();
        }
      }
    }

    void errorHandler(e, trace) {
      String msg = "Socket error $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    }

    connection.listen(dataReceived, onError: errorHandler);
  }
}

main() {
  asyncStart();
  EchoServerGame echoServerGame = new EchoServerGame.start();
}
