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

// @dart = 2.9

// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--no-enable-isolate-groups
//
// OtherResources=readline_test1.dat
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

library ServerTest;

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

part "testing_server.dart";

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

bool compareFileContent(String fileName1, String fileName2) {
  var contents1 = new File(fileName1).readAsStringSync();
  var contents2 = new File(fileName2).readAsStringSync();
  return contents1 == contents2;
}

// This test does:
//  1. Opens a socket to the testing server.
//  2. Pipes the content of a file to that sockets input stream.
//  3. Creates a temp file.
//  4. Pipes the socket output stream to the temp file.
//  5. Expects the original file and the temp file to be equal.
class PipeServerGame {
  int count = 0;

  PipeServerGame.start() : _messages = 0 {
    initialize();
  }

  void runTest() {
    void connectHandler() {
      String srcFileName = getDataFilename("readline_test1.dat");
      Stream fileInput = new File(srcFileName).openRead();
      fileInput.cast<List<int>>().pipe(_socket).then((_) {
        var tempDir = Directory.systemTemp.createTempSync('dart_pipe_server');
        var dstFileName = tempDir.path + "/readline_test1.dat";
        var dstFile = new File(dstFileName);
        dstFile.createSync();
        var fileOutput = dstFile.openWrite();
        _socket.cast<List<int>>().pipe(fileOutput).then((_) {
          // Check that the resulting file is equal to the initial
          // file.
          bool result = compareFileContent(srcFileName, dstFileName);
          new File(dstFileName).deleteSync();
          tempDir.deleteSync();
          Expect.isTrue(result);

          // Run this twice.
          if (count++ < 2) {
            runTest();
          } else {
            shutdown();
          }
        });
      });
    }

    // Connect to the server.
    Socket.connect(TestingServer.HOST, _port).then((s) {
      _socket = s;
      connectHandler();
    });
  }

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

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

  int _port;
  SendPort _closeSendPort;
  Socket _socket;
  int _messages;
}

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

// The testing server will simply pipe each connecting sockets input
// stream to its output stream.
class PipeServer extends TestingServer {
  void onConnection(Socket connection) {
    connection.cast<List<int>>().pipe(connection);
  }
}

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