library fileapi;

import 'package:unittest/unittest.dart';
import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:async';

class FileAndDir {
  FileEntry file;
  DirectoryEntry dir;
  FileAndDir(this.file, this.dir);
}

FileSystem fs;

main() {
  useHtmlIndividualConfiguration();

  group('supported', () {
    test('supported', () {
      expect(FileSystem.supported, true);
    });
  });

  getFileSystem() {
    return window.requestFileSystem(100).then((FileSystem fileSystem) {
      fs = fileSystem;
    });
  }

  group('unsupported_throws', () {
    test('requestFileSystem', () {
      var expectation = FileSystem.supported ? returnsNormally : throws;
      expect(() {
        window.requestFileSystem(100);
      }, expectation);
    });
  });

  group('getDirectory', () {
    if (FileSystem.supported) {
      test('getFileSystem', getFileSystem);

      test('directoryDoesntExist', () {
        return fs.root.getDirectory('directory2').catchError((error) {
          expect(error.code, equals(DomException.NOT_FOUND));
        }, test: (e) => e is DomError);
      });

      test('directoryCreate', () {
        return fs.root.createDirectory('directory3').then((DirectoryEntry e) {
          expect(e.name, equals('directory3'));
        });
      });
    }
  });

  group('getFile', () {
    if (FileSystem.supported) {
      test('getFileSystem', getFileSystem);

      test('fileDoesntExist', () {
        return fs.root.getFile('file2').catchError((error) {
          expect(error.code, equals(DomException.NOT_FOUND));
        }, test: (e) => e is DomError);
      });

      test('fileCreate', () {
        return fs.root.createFile('file4').then((FileEntry e) {
          expect(e.name, equals('file4'));
          expect(e.isFile, isTrue);
          return e.getMetadata();
        }).then((Metadata metadata) {
          var changeTime = metadata.modificationTime;
          // Upped because our Windows buildbots can sometimes be particularly
          // slow.
          expect(
              new DateTime.now().difference(changeTime).inMinutes, lessThan(4));
          expect(metadata.size, equals(0));
        });
      });
    }
  });

  // Do the boilerplate to get several files and directories created to then
  // test the functions that use those items.
  Future doDirSetup(String testName) {
    return fs.root.createFile('file_$testName').then((FileEntry file) {
      return fs.root
          .createDirectory('dir_$testName')
          .then((DirectoryEntry dir) {
        return new Future.value(new FileAndDir(file, dir));
      });
    });
  }

  group('directoryReader', () {
    if (FileSystem.supported) {
      test('getFileSystem', getFileSystem);

      test('readEntries', () {
        return doDirSetup('readEntries').then((fileAndDir) {
          var reader = fileAndDir.dir.createReader();
          return reader.readEntries();
        }).then((entries) {
          expect(entries is List, true);
        });
      });
    }
  });

  group('entry', () {
    if (FileSystem.supported) {
      test('getFileSystem', getFileSystem);

      test('copyTo', () {
        return doDirSetup('copyTo').then((fileAndDir) {
          return fileAndDir.file.copyTo(fileAndDir.dir, name: 'copiedFile');
        }).then((entry) {
          expect(entry.isFile, true);
          expect(entry.name, 'copiedFile');
        });
      });

      test('getParent', () {
        return doDirSetup('getParent').then((fileAndDir) {
          return fileAndDir.file.getParent();
        }).then((entry) {
          expect(entry.name, '');
          expect(entry.isFile, false);
        });
      });

      test('moveTo', () {
        return doDirSetup('moveTo').then((fileAndDir) {
          return fileAndDir.file.moveTo(fileAndDir.dir, name: 'movedFile');
        }).then((entry) {
          expect(entry.name, 'movedFile');
          expect(entry.fullPath, '/dir_moveTo/movedFile');
          return fs.root.getFile('file4');
        }).catchError((error) {
          expect(error.code, equals(DomException.NOT_FOUND));
        }, test: (e) => e is DomError);
      });

      test('remove', () {
        return doDirSetup('remove').then((fileAndDir) {
          return fileAndDir.file.remove().then((_) {});
        });
      });
    }
  });

  group('fileEntry', () {
    if (FileSystem.supported) {
      test('getFileSystem', getFileSystem);

      test('createWriter', () {
        return doDirSetup('createWriter').then((fileAndDir) {
          return fileAndDir.file.createWriter();
        }).then((writer) {
          expect(writer.position, 0);
          expect(writer.readyState, FileWriter.INIT);
          expect(writer.length, 0);
        });
      });

      test('file', () {
        return doDirSetup('file').then((fileAndDir) {
          return fileAndDir.file.file().then((fileObj) {
            expect(fileObj.name, fileAndDir.file.name);
            expect(fileObj.relativePath, '');
            expect(
                new DateTime.now()
                    .difference(fileObj.lastModifiedDate)
                    .inSeconds,
                lessThan(60));
          });
        });
      });
    }
  });
}
