// 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=fixed_length_file

import "dart:async";
import "dart:io";

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

void testReadInvalidArgs(arg) {
  String filename = getFilename("fixed_length_file");
  var file = (new File(filename)).openSync();
  Expect.throws(() => file.readSync(arg), (e) => e is ArgumentError);

  Expect.throws(() => file.read(arg), (e) => e is ArgumentError);
  file.closeSync();
}

void testReadIntoInvalidArgs(buffer, start, end) {
  String filename = getFilename("fixed_length_file");
  var file = (new File(filename)).openSync();
  Expect.throws(
      () => file.readIntoSync(buffer, start, end), (e) => e is ArgumentError);

  Expect.throws(
      () => file.readInto(buffer, start, end), (e) => e is ArgumentError);
  file.closeSync();
}

void testWriteByteInvalidArgs(value) {
  String filename = getFilename("fixed_length_file");
  var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
  Expect.throws(() => file.writeByteSync(value), (e) => e is ArgumentError);

  Expect.throws(() => file.writeByte(value), (e) => e is ArgumentError);
  file.closeSync();
}

void testWriteFromInvalidArgs(buffer, start, end) {
  String filename = getFilename("fixed_length_file");
  var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
  Expect.throws(
      () => file.writeFromSync(buffer, start, end), (e) => e is ArgumentError);

  Expect.throws(
      () => file.writeFrom(buffer, start, end), (e) => e is ArgumentError);
  file.closeSync();
}

void testWriteStringInvalidArgs(string, encoding) {
  String filename = getFilename("fixed_length_file");
  var file = new File("${filename}_out").openSync(mode: FileMode.WRITE);
  Expect.throws(() => file.writeStringSync(string, encoding: encoding),
      (e) => e is ArgumentError);

  Expect.throws(() => file.writeString(string, encoding: encoding),
      (e) => e is ArgumentError);
  file.closeSync();
}

Future futureThrows(Future result) {
  return result.then((value) {
    throw new ExpectException(
        "futureThrows received $value instead of an exception");
  }, onError: (_) => null);
}

void testFileSystemEntity() {
  Expect.throws(() => ((x) => FileSystemEntity.typeSync(x))([1, 2, 3]));
  Expect.throws(() => ((x, y) =>
      FileSystemEntity.typeSync(x, followLinks: y))(".", "why not?"));
  Expect.throws(
      () => ((x, y) => FileSystemEntity.identicalSync(x, y))([1, 2, 3], "."));
  Expect
      .throws(() => ((x, y) => FileSystemEntity.identicalSync(x, y))(".", 52));
  Expect.throws(() => ((x) => FileSystemEntity.isLinkSync(x))(52));
  Expect.throws(() => ((x) => FileSystemEntity.isFileSync(x))(52));
  Expect.throws(() => ((x) => FileSystemEntity.isDirectorySync(x))(52));

  asyncStart();
  futureThrows(((x) => FileSystemEntity.type(x))([1, 2, 3]))
      .then((_) => futureThrows(((x, y) =>
          FileSystemEntity.type(x, followLinks: y))(".", "why not?")))
      .then((_) => futureThrows(
          ((x, y) => FileSystemEntity.identical(x, y))([1, 2, 3], ".")))
      .then((_) =>
          futureThrows(((x, y) => FileSystemEntity.identical(x, y))(".", 52)))
      .then((_) => futureThrows(((x) => FileSystemEntity.isLink(x))(52)))
      .then((_) => futureThrows(((x) => FileSystemEntity.isFile(x))(52)))
      .then((_) => futureThrows(((x) => FileSystemEntity.isDirectory(x))(52)))
      .then((_) => asyncEnd());
}

String getFilename(String path) {
  return Platform.script.resolve(path).toFilePath();
}

main() {
  testReadInvalidArgs('asdf');
  testReadIntoInvalidArgs(12, 0, 1);
  testReadIntoInvalidArgs(new List(10), '0', 1);
  testReadIntoInvalidArgs(new List(10), 0, '1');
  testWriteByteInvalidArgs('asdf');
  testWriteFromInvalidArgs(12, 0, 1);
  testWriteFromInvalidArgs(new List(10), '0', 1);
  testWriteFromInvalidArgs(new List(10), 0, '1');
  testWriteStringInvalidArgs("Hello, world", 42);
  testFileSystemEntity();
}
