// Copyright (c) 2015, 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_lock_script.dart

import 'dart:async';
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.
check(String path, int start, int end, FileLock mode, {bool locked}) {
  // Client process returns either 'LOCK FAILED' or 'LOCK SUCCEEDED'.
  var expected = locked ? 'LOCK FAILED' : 'LOCK SUCCEEDED';
  var arguments = <String>[]
    ..addAll(Platform.executableArguments)
    ..add(Platform.script.resolve('file_lock_script.dart').toFilePath())
    ..add(path)
    ..add(mode == FileLock.exclusive ? 'EXCLUSIVE' : 'SHARED')
    ..add('$start')
    ..add('$end');
  return Process
      .run(Platform.executable, arguments)
      .then((ProcessResult result) {
    if (result.exitCode != 0 || !result.stdout.contains(expected)) {
      print("Client failed, exit code ${result.exitCode}");
      print("  stdout:");
      print(result.stdout);
      print("  stderr:");
      print(result.stderr);
      print("  arguments:");
      print(arguments);
      Expect.fail('Client subprocess exit code: ${result.exitCode}');
    }
  });
}

checkLocked(String path,
        [int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
    check(path, start, end, mode, locked: true);

checkNotLocked(String path,
        [int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
    check(path, start, end, mode, locked: false);

void testLockWholeFile() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.write);
  raf.lockSync();
  asyncStart();
  checkLocked(file.path).then((_) {
    return checkLocked(file.path, 0, 2).then((_) {
      raf.unlockSync();
      return checkNotLocked(file.path).then((_) {});
    });
  }).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockWholeFileAsync() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.write);
  asyncStart();
  Future.forEach([
    () => raf.lock(),
    () => checkLocked(file.path, 0, 2),
    () => checkLocked(file.path),
    () => raf.unlock(),
    () => checkNotLocked(file.path),
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockRange() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf1 = file.openSync(mode: FileMode.write);
  var raf2 = file.openSync(mode: FileMode.write);
  asyncStart();
  var tests = [
    () => raf1.lockSync(FileLock.exclusive, 2, 3),
    () => raf2.lockSync(FileLock.exclusive, 5, 7),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkNotLocked(file.path, 4, 5),
    () => checkLocked(file.path, 4, 6),
    () => checkLocked(file.path, 6),
    () => checkNotLocked(file.path, 7),
    () => raf1.unlockSync(2, 3),
    () => checkNotLocked(file.path, 0, 5),
    () => checkLocked(file.path, 4, 6),
    () => checkLocked(file.path, 6),
    () => checkNotLocked(file.path, 7),
  ];
  // On Windows regions unlocked must match regions locked.
  if (!Platform.isWindows) {
    tests.addAll([
      () => raf1.unlockSync(5, 6),
      () => checkNotLocked(file.path, 0, 6),
      () => checkLocked(file.path, 6),
      () => checkNotLocked(file.path, 7),
      () => raf2.unlockSync(6, 7),
      () => checkNotLocked(file.path)
    ]);
  } else {
    tests
        .addAll([() => raf2.unlockSync(5, 7), () => checkNotLocked(file.path)]);
  }
  Future.forEach(tests, (f) => f()).whenComplete(() {
    raf1.closeSync();
    raf2.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockRangeAsync() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf1 = file.openSync(mode: FileMode.write);
  var raf2 = file.openSync(mode: FileMode.write);
  asyncStart();
  var tests = [
    () => raf1.lock(FileLock.exclusive, 2, 3),
    () => raf2.lock(FileLock.exclusive, 5, 7),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkNotLocked(file.path, 4, 5),
    () => checkLocked(file.path, 4, 6),
    () => checkLocked(file.path, 6),
    () => checkNotLocked(file.path, 7),
    () => raf1.unlock(2, 3),
    () => checkNotLocked(file.path, 0, 5),
    () => checkLocked(file.path, 4, 6),
    () => checkLocked(file.path, 6),
    () => checkNotLocked(file.path, 7),
  ];
  // On Windows regions unlocked must match regions locked.
  if (!Platform.isWindows) {
    tests.addAll([
      () => raf1.unlock(5, 6),
      () => checkNotLocked(file.path, 0, 6),
      () => checkLocked(file.path, 6),
      () => checkNotLocked(file.path, 7),
      () => raf2.unlock(6, 7),
      () => checkNotLocked(file.path)
    ]);
  } else {
    tests.addAll([() => raf2.unlock(5, 7), () => checkNotLocked(file.path)]);
  }
  Future.forEach(tests, (f) => f()).whenComplete(() {
    raf1.closeSync();
    raf2.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockEnd() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.append);
  asyncStart();
  Future.forEach([
    () => raf.lockSync(FileLock.exclusive, 2),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkLocked(file.path, 9),
    () => raf.writeFromSync(new List.filled(10, 0)),
    () => checkLocked(file.path, 10),
    () => checkLocked(file.path, 19),
    () => raf.unlockSync(2),
    () => checkNotLocked(file.path)
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockEndAsync() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.append);
  asyncStart();
  Future.forEach([
    () => raf.lock(FileLock.exclusive, 2),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkLocked(file.path, 9),
    () => raf.writeFromSync(new List.filled(10, 0)),
    () => checkLocked(file.path, 10),
    () => checkLocked(file.path, 19),
    () => raf.unlock(2),
    () => checkNotLocked(file.path)
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockShared() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync();
  asyncStart();
  Future.forEach([
    () => raf.lock(FileLock.shared),
    () => checkLocked(file.path),
    () => checkLocked(file.path, 0, 2),
    () => checkNotLocked(file.path, 0, 2, FileLock.shared)
  ], (f) => f()).then((_) {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockSharedAsync() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync();
  asyncStart();
  Future.forEach([
    () => raf.lock(FileLock.shared),
    () => checkLocked(file.path),
    () => checkLocked(file.path, 0, 2),
    () => checkNotLocked(file.path, 0, 2, FileLock.shared)
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockAfterLength() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.append);
  asyncStart();
  Future.forEach([
    () => raf.lockSync(FileLock.exclusive, 2, 15),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkLocked(file.path, 9),
    () => checkLocked(file.path, 14),
    () => raf.writeFromSync(new List.filled(10, 0)),
    () => checkLocked(file.path, 10),
    () => checkNotLocked(file.path, 15),
    () => raf.unlockSync(2, 15),
    () => checkNotLocked(file.path)
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void testLockAfterLengthAsync() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
  File file = new File(join(directory.path, "file"));
  file.writeAsBytesSync(new List.filled(10, 0));
  var raf = file.openSync(mode: FileMode.append);
  asyncStart();
  Future.forEach([
    () => raf.lock(FileLock.exclusive, 2, 15),
    () => checkNotLocked(file.path, 0, 2),
    () => checkLocked(file.path, 0, 3),
    () => checkLocked(file.path, 9),
    () => checkLocked(file.path, 14),
    () => raf.writeFromSync(new List.filled(10, 0)),
    () => checkLocked(file.path, 10),
    () => checkNotLocked(file.path, 15),
    () => raf.unlock(2, 15),
    () => checkNotLocked(file.path)
  ], (f) => f()).whenComplete(() {
    raf.closeSync();
    directory.deleteSync(recursive: true);
    asyncEnd();
  });
}

void main() {
  testLockWholeFile();
  testLockWholeFileAsync();
  testLockRange();
  testLockRangeAsync();
  testLockEnd();
  testLockEndAsync();
  testLockShared();
  testLockSharedAsync();
  testLockAfterLength();
  testLockAfterLengthAsync();
}
