library file_sample;

import 'dart:async';
import 'dart:html';

import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
import 'package:async_helper/async_helper.dart';

// Expected output from all functions, asynchronous, and event routines.
const String log_results = 'test-first\n' +
    'acquire START\n' +
    'acquire CALLBACK START\n' +
    'acquire CALLBACK END\n' +
    'first START\n' +
    'first END\n' +
    'test-second\n' +
    'second START\n' +
    'second END\n' +
    'reader onLoadEnd event\n' +
    'file content = XYZZY Output\n';

// Simple logger to record all output.
class Logger {
  StringBuffer _log = new StringBuffer();

  void log(String message) {
    _log.writeln(message);
  }

  String get contents => _log.toString();
}

Logger testLog = new Logger();

Future<FileSystem> _fileSystem;

Future<FileSystem> get fileSystem async {
  if (_fileSystem != null) return _fileSystem;

  testLog.log('acquire START');
  _fileSystem = window.requestFileSystem(100);

  var fs = await _fileSystem;
  testLog.log('acquire CALLBACK START');
  expect(fs != null, true);
  expect(fs.root != null, true);
  expect(fs.runtimeType, FileSystem);
  expect(fs.root.runtimeType, DirectoryEntry);
  testLog.log('acquire CALLBACK END');

  return _fileSystem;
}

Future<FileEntry> createFile() async {
  var fs = await fileSystem;

  FileEntry fileEntry = await fs.root.createFile('log.txt');

  expect(fileEntry.isFile, true);
  expect(fileEntry.name, 'log.txt');
  expect(fileEntry.fullPath, '/log.txt');

  FileWriter writer = await fileEntry.createWriter();

  Blob blob = new Blob(['XYZZY Output'], 'text/plain');

  writer.write(blob);

  var reader = new FileReader();

  var completer = new Completer<String>();

  reader.onLoadEnd.listen((event) {
    testLog.log('reader onLoadEnd event');
    dynamic target = event.currentTarget;
    testLog.log('file content = ${target.result}');
    expect(target.result, 'XYZZY Output');

    completer.complete(target.result);
  });

  Blob readBlob = await fileEntry.file();

  reader.readAsText(readBlob);

  // Wait until onLoadEnd if fired.
  await completer.future;

  return new Future<FileEntry>.value(fileEntry);
}

main() {
  useHtmlConfiguration();

  group('test FileSystem', () {
    test('FileSystem request #1', () async {
      testLog.log('test-first');
      var fs = await fileSystem;
      testLog.log('first START');
      expect(fs != null, true);
      expect(fs.root != null, true);
      expect(fs.runtimeType, FileSystem);
      expect(fs.root.runtimeType, DirectoryEntry);
      testLog.log('first END');
    });

    test('FileSystem request, create, R/W', () async {
      testLog.log('test-second');
      var fs = await fileSystem;
      testLog.log('second START');
      expect(fs != null, true);
      expect(fs.root != null, true);
      expect(fs.runtimeType, FileSystem);
      expect(fs.root.runtimeType, DirectoryEntry);
      testLog.log('second END');

      FileEntry fileEntry = await createFile();
      expect(fileEntry.name, 'log.txt');

      // Validate every function, async and event mechanism successfully ran.
      expect(testLog.contents, log_results);
    });
  });
}
