// Copyright (c) 2017, 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.

/// @assertion Stream<FileSystemEntity> list({
///  bool recursive: false,
///  bool followLinks: true
///  })
/// Lists the sub-directories and files of this Directory. Optionally recurses
/// into sub-directories.
///
/// If followLinks is false, then any symbolic links found are reported as Link
/// objects, rather than as directories or files, and are not recursed into.
///
/// If followLinks is true, then working links are reported as directories or
/// files, depending on their type, and links to directories are recursed into.
/// Broken links are reported as Link objects. If a symbolic link makes a loop in
/// the file system, then a recursive listing will not follow a link twice in the
/// same recursive descent, but will report it as a Link the second time it is
/// seen.
///
/// The result is a stream of FileSystemEntity objects for the directories,
/// files, and links.
/// @description Checks that if recursive parameter false then subdirectories are
/// not listed
/// @author sgrekhov@unipro.ru

import "dart:io";
import "../../../Utils/expect.dart";
import "../file_utils.dart";

List<String> setUp(Directory parent, Map directories) {
  List<String> expected = new List<String>.empty(growable: true);
  directories.forEach((key, value) {
    Directory dir = new Directory(parent.path + Platform.pathSeparator + key);
    dir.createSync();
    expected.add(dir.path);
    if (value != null) {
      setUp(dir, value);
    }
  });
  return expected;
}

Map getContent(Directory dir) {
  Map found = new Map();
  dir.list(recursive: true).forEach((entity) {
      found.addAll({entity.path: null});
  });
  return found;
}

main() async {
  await inSandbox(_main);
}

_main(Directory sandbox) async {
  Directory dir = sandbox;
  asyncStart();
  Map struct = {"a": null, "b": null, "c": {"c1": null, "c2": null}, "d": null};
  List<String> expected = setUp(dir, struct);

  List<String> found = new List<String>.empty(growable: true);
  await dir.list(recursive: false).forEach((entity) {
    found.add(entity.path);
  }).then((_) {
    Expect.setEquals(new Set.from(expected), new Set.from(found));
    asyncEnd();
  });
}
