// 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.
//
// OtherResources=readline_test1.dat
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

// @dart = 2.9

import "dart:io";

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

// Helper method to be able to run the test from the runtime
// directory, or the top directory.
String getDataFilename(String path) =>
    Platform.script.resolve(path).toFilePath();

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.readIntoSync(data1, 0, count);
  Expect.equals(count, read1);
  var read2 = file2.readIntoSync(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.
  asyncStart();

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

  var tempDir = Directory.systemTemp.createTempSync('dart_stream_pipe');
  String dstFileName = tempDir.path + "/readline_test1.dat";
  new File(dstFileName).createSync();
  var output = new File(dstFileName).openWrite();
  srcStream.cast<List<int>>().pipe(output).then((_) {
    bool result = compareFileContent(srcFileName, dstFileName);
    new File(dstFileName).deleteSync();
    tempDir.deleteSync();
    Expect.isTrue(result);
    asyncEnd();
  });
}

// 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.
  asyncStart();

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

  var tempDir = Directory.systemTemp.createTempSync('dart_stream_pipe');
  var dstFileName = tempDir.path + "/readline_test1.dat";
  var dstFile = new File(dstFileName);
  dstFile.createSync();
  var output = dstFile.openWrite();
  output.addStream(srcStream.cast<List<int>>()).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.readIntoSync(data, 0, 1);
      Expect.equals(32, data[0]);
      src.closeSync();
      dst.closeSync();
      dstFile.deleteSync();
      tempDir.deleteSync();
      asyncEnd();
    });
  });
}

// Test piping two copies of one file to another.
testFileToFilePipe3() {
  // Force test to timeout if one of the handlers is
  // not called.
  asyncStart();

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

  var tempDir = Directory.systemTemp.createTempSync('dart_stream_pipe');
  var dstFileName = tempDir.path + "/readline_test1.dat";
  var dstFile = new File(dstFileName);
  dstFile.createSync();
  var output = dstFile.openWrite();
  output.addStream(srcStream.cast<List<int>>()).then((_) {
    var srcStream2 = srcFile.openRead();
    output.addStream(srcStream2.cast<List<int>>()).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();
        asyncEnd();
      });
    });
  });
}

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