// Copyright (c) 2016, 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=file_blocking_lock_script.dart

// This test works by spawning a new process running
// file_blocking_lock_script.dart, trading the file lock back and forth,
// writing bytes 1 ... 25 in order to the file. There are checks to ensure
// that the bytes are written in order, that one process doesn't write all the
// bytes and that a non-blocking lock fails such that a blocking lock must
// be taken, which succeeds.

import 'dart:async';
import 'dart:convert';
import 'dart:io';

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

// Check whether the file is locked or not.
runPeer(String path, int len, FileLock mode) {
  var script = Platform.script.resolve(
      'file_blocking_lock_script.dart').toFilePath();
  var arguments = []
      ..addAll(Platform.executableArguments)
      ..add(script)
      ..add(path)
      ..add(len.toString());
  return Process.start(Platform.executable, arguments).then((process) {
    process.stdout
        .transform(UTF8.decoder)
        .listen((data) { print(data); });
    process.stderr
        .transform(UTF8.decoder)
        .listen((data) { print(data); });
    return process;
  });
}

const int peerTimeoutMilliseconds = 10000;

Future<bool> waitForPeer(RandomAccessFile raf, int length) async {
  Stopwatch s = new Stopwatch();
  s.start();
  while (true) {
    await raf.unlock(0, length);
    if (s.elapsedMilliseconds > peerTimeoutMilliseconds) {
      s.stop();
      return false;
    }
    try {
      await raf.lock(FileLock.EXCLUSIVE, 0, length);
    } on dynamic {
      await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length);
      break;
    }
  }
  s.stop();
  return true;
}

testLockWholeFile() async {
  const int length = 25;
  Directory directory = await Directory.systemTemp.createTemp('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  await file.writeAsBytes(new List.filled(length, 0));
  var raf = await file.open(mode: APPEND);
  await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length);
  Process peer = await runPeer(file.path, length, FileLock.BLOCKING_EXCLUSIVE);

  // Waits for the peer to take the lock, then takes the lock.
  Expect.isTrue(await waitForPeer(raf, length));

  // Check that the peer wrote to the file.
  int p = 0;
  await raf.setPosition(0);
  while (p < length) {
    int at = await raf.readByte();
    Expect.equals(1, at);
    p++;
  }
  await raf.unlock(0, length);

  // Check that the peer exited successfully.
  int v = await peer.exitCode;
  Expect.equals(0, v);
  await raf.close();
  await directory.delete(recursive: true);
}

main() async {
  asyncStart();
  await testLockWholeFile();
  asyncEnd();
}
