// Copyright (c) 2012, 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=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
library ServerTest;

import "dart:io";
import "dart:isolate";

// Helper method to be able to run the test from the runtime
// directory, or the top directory.
String getDataFilename(String path) =>
    new File(path).existsSync() ? path : '../$path';


bool compareFileContent(String fileName1,
                        String fileName2,
                        {int file1Offset: 0,
                         int file2Offset: 0,
                         int count}) {
  var file1 = new File(fileName1).openSync();
  var file2 = new File(fileName2).openSync();
  var length1 = file1.lengthSync();
  var length2 = file2.lengthSync();
  if (file1Offset == 0 && file2Offset == 0 && count == null) {
    if (length1 != length2) {
      file1.closeSync();
      file2.closeSync();
      return false;
    }
  }
  if (count == null) count = length1;
  var data1 = new List<int>(count);
  var data2 = new List<int>(count);
  if (file1Offset != 0) file1.setPositionSync(file1Offset);
  if (file2Offset != 0) file2.setPositionSync(file2Offset);
  var read1 = file1.readListSync(data1, 0, count);
  Expect.equals(count, read1);
  var read2 = file2.readListSync(data2, 0, count);
  Expect.equals(count, read2);
  for (var i = 0; i < count; i++) {
    if (data1[i] != data2[i]) {
      file1.closeSync();
      file2.closeSync();
      return false;
    }
  }
  file1.closeSync();
  file2.closeSync();
  return true;
}


// Test piping from one file to another and closing both streams
// after wards.
testFileToFilePipe1() {
  // Force test to timeout if one of the handlers is
  // not called.
  ReceivePort donePort = new ReceivePort();
  donePort.receive((message, ignore) { donePort.close(); });

  String srcFileName =
      getDataFilename("tests/standalone/io/readline_test1.dat");
  var srcStream = new File(srcFileName).openRead();

  var tempDir = new Directory('').createTempSync();
  String dstFileName = tempDir.path.concat("/readline_test1.dat");
  new File(dstFileName).createSync();
  var output = new File(dstFileName).openWrite();
  srcStream.pipe(output).then((_) {
    bool result = compareFileContent(srcFileName, dstFileName);
    new File(dstFileName).deleteSync();
    tempDir.deleteSync();
    Expect.isTrue(result);
    donePort.toSendPort().send(null);
  });
}


// Test piping from one file to another and write additional data to
// the output stream after piping finished.
testFileToFilePipe2() {
  // Force test to timeout if one of the handlers is
  // not called.
  ReceivePort donePort = new ReceivePort();
  donePort.receive((message, ignore) { donePort.close(); });

  String srcFileName =
      getDataFilename("tests/standalone/io/readline_test1.dat");
  var srcFile = new File(srcFileName);
  var srcStream = srcFile.openRead();

  var tempDir = new Directory('').createTempSync();
  var dstFileName = tempDir.path.concat("/readline_test1.dat");
  var dstFile = new File(dstFileName);
  dstFile.createSync();
  var output = dstFile.openWrite();
  output.addStream(srcStream).then((_) {
    output.add([32]);
    output.close();
    output.done.then((_) {
      var src = srcFile.openSync();
      var dst = dstFile.openSync();
      var srcLength = src.lengthSync();
      var dstLength = dst.lengthSync();
      Expect.equals(srcLength + 1, dstLength);
      Expect.isTrue(compareFileContent(srcFileName,
                                       dstFileName,
                                       count: srcLength));
      dst.setPositionSync(srcLength);
      var data = new List<int>(1);
      var read2 = dst.readListSync(data, 0, 1);
      Expect.equals(32, data[0]);
      src.closeSync();
      dst.closeSync();
      dstFile.deleteSync();
      tempDir.deleteSync();
      donePort.toSendPort().send(null);
    });
  });
}


// Test piping two copies of one file to another.
testFileToFilePipe3() {
  // Force test to timeout if one of the handlers is
  // not called.
  ReceivePort donePort = new ReceivePort();
  donePort.receive((message, ignore) { donePort.close(); });

  String srcFileName =
      getDataFilename("tests/standalone/io/readline_test1.dat");
  var srcFile = new File(srcFileName);
  var srcStream = srcFile.openRead();

  var tempDir = new Directory('').createTempSync();
  var dstFileName = tempDir.path.concat("/readline_test1.dat");
  var dstFile = new File(dstFileName);
  dstFile.createSync();
  var output = dstFile.openWrite();
  output.addStream(srcStream).then((_) {
    var srcStream2 = srcFile.openRead();
    output.addStream(srcStream2).then((_) {
      output.close();
      output.done.then((_) {
        var src = srcFile.openSync();
        var dst = dstFile.openSync();
        var srcLength = src.lengthSync();
        var dstLength = dst.lengthSync();
        Expect.equals(srcLength * 2, dstLength);
        Expect.isTrue(compareFileContent(srcFileName,
                                         dstFileName,
                                         count: srcLength));
        Expect.isTrue(compareFileContent(srcFileName,
                                         dstFileName,
                                         file2Offset: srcLength,
                                         count: srcLength));
        src.closeSync();
        dst.closeSync();
        dstFile.deleteSync();
        tempDir.deleteSync();
        donePort.toSendPort().send(null);
      });
    });
  });
}


main() {
  testFileToFilePipe1();
  testFileToFilePipe2();
  testFileToFilePipe3();
}
