// 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.

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

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

void testReadInvalidArgs(arg) {
  String filename = getFilename("tests/vm/data/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);
}

void testReadIntoInvalidArgs(buffer, start, end) {
  String filename = getFilename("tests/vm/data/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);
}

void testWriteByteInvalidArgs(value) {
  String filename = getFilename("tests/vm/data/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);
}

void testWriteFromInvalidArgs(buffer, start, end) {
  String filename = getFilename("tests/vm/data/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);
}

void testWriteStringInvalidArgs(string, encoding) {
  String filename = getFilename("tests/vm/data/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);
}

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 new File(path).existsSync() ? path : 'runtime/$path';
}

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();
}
