// Copyright (c) 2012, 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.
//
// Directory listing test.

// @dart = 2.9

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

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

class DirectoryTest {
  static void testListing() {
    bool listedDir = false;
    bool listedFile = false;

    Directory directory =
        Directory.systemTemp.createTempSync('dart_directory_test');
    Directory subDirectory = new Directory("${directory.path}/subdir");
    Expect.isTrue('$directory'.contains(directory.path));
    Expect.isFalse(subDirectory.existsSync());
    subDirectory.createSync();
    Expect.isTrue(subDirectory.existsSync());
    File f = new File('${subDirectory.path}/file.txt');
    File fLong = new File('${directory.path}/subdir/../subdir/file.txt');
    Expect.isFalse(f.existsSync());
    f.createSync();

    void testSyncListing(bool recursive) {
      for (var entry in directory.listSync(recursive: recursive)) {
        if (entry is File) {
          Expect.isTrue(entry.path.contains(directory.path));
          Expect.isTrue(entry.path.contains('subdir'));
          Expect.isTrue(entry.path.contains('file.txt'));
          Expect.isFalse(listedFile);
          listedFile = true;
        } else {
          Expect.isTrue(entry is Directory);
          Expect.isTrue(entry.path.contains(directory.path));
          Expect.isTrue(entry.path.contains('subdir'));
          Expect.isFalse(listedDir);
          listedDir = true;
        }
      }
      Expect.equals(listedFile, recursive);
      Expect.isTrue(listedDir);
      listedFile = false;
      listedDir = false;
    }

    testSyncListing(true);
    testSyncListing(false);
    Expect.equals(
        f.resolveSymbolicLinksSync(), fLong.resolveSymbolicLinksSync());

    asyncStart();
    directory.list(recursive: true).listen((FileSystemEntity entity) {
      if (entity is File) {
        var path = entity.path;
        listedFile = true;
        Expect.isTrue(path.contains(directory.path));
        Expect.isTrue(path.contains('subdir'));
        Expect.isTrue(path.contains('file.txt'));
      } else {
        var path = entity.path;
        Expect.isTrue(entity is Directory);
        listedDir = true;
        Expect.isTrue(path.contains(directory.path));
        Expect.isTrue(path.contains('subdir'));
      }
    }, onDone: () {
      Expect.isTrue(listedDir, "directory not found");
      Expect.isTrue(listedFile, "file not found");
      directory.delete(recursive: true).then((ignore) {
        f.exists().then((exists) => Expect.isFalse(exists));
        directory.exists().then((exists) => Expect.isFalse(exists));
        subDirectory.exists().then((exists) => Expect.isFalse(exists));
        asyncEnd();
      });
    });

    // Listing is asynchronous, so nothing should be listed at this
    // point.
    Expect.isFalse(listedDir);
    Expect.isFalse(listedFile);
  }

  static void testListingTailingPaths() {
    Directory directory =
        Directory.systemTemp.createTempSync('dart_directory_test');
    Directory subDirectory = new Directory("${directory.path}/subdir/");
    subDirectory.createSync();
    File f = new File('${subDirectory.path}/file.txt');
    f.createSync();

    void test(entry) {
      Expect.isFalse(entry.path.contains(new RegExp('[\\/][\\/]')));
    }

    subDirectory.listSync().forEach(test);

    subDirectory.list().listen(test, onDone: () {
      directory.deleteSync(recursive: true);
    });
  }

  static void testListNonExistent() {
    setupListerHandlers(Stream<FileSystemEntity> stream) {
      stream.listen(
          (_) => Expect.fail("Listing of non-existing directory should fail"),
          onError: (error) {
        Expect.isTrue(error is FileSystemException);
      });
    }

    Directory.systemTemp.createTemp('dart_directory').then((d) {
      d.delete().then((ignore) {
        setupListerHandlers(d.list());
        setupListerHandlers(d.list(recursive: true));
      });
    });
  }

  static void testListTooLongName() {
    asyncStart();
    Directory.systemTemp.createTemp('dart_directory').then((d) {
      var errors = 0;
      setupListHandlers(Stream<FileSystemEntity> stream) {
        stream.listen(
            (_) => Expect.fail("Listing of non-existing directory should fail"),
            onError: (error) {
          Expect.isTrue(error is FileSystemException);
          if (++errors == 2) {
            d.delete(recursive: true).then((_) {
              asyncEnd();
            });
          }
        });
      }

      var subDirName = 'subdir';
      var subDir = new Directory("${d.path}/$subDirName");
      subDir.create().then((ignore) {
        // Construct a long string of the form
        // 'tempdir/subdir/../subdir/../subdir'.
        var buffer = new StringBuffer();
        buffer.write(subDir.path);
        for (var i = 0; i < 1000; i++) {
          buffer.write("/../${subDirName}");
        }
        var long = new Directory("${buffer.toString()}");
        setupListHandlers(long.list());
        setupListHandlers(long.list(recursive: true));
      });
    });
  }

  static void testDeleteNonExistent() {
    // Test that deleting a non-existing directory fails.
    setupFutureHandlers(future) {
      future.then((ignore) {
        Expect.fail("Deletion of non-existing directory should fail");
      }).catchError((error) {
        Expect.isTrue(error is FileSystemException);
      });
    }

    Directory.systemTemp.createTemp('dart_directory').then((d) {
      d.delete().then((ignore) {
        setupFutureHandlers(d.delete());
        setupFutureHandlers(d.delete(recursive: true));
      });
    });
  }

  static void testDeleteTooLongName() {
    asyncStart();
    Directory.systemTemp.createTemp('dart_directory').then((d) {
      var subDirName = 'subdir';
      var subDir = new Directory("${d.path}/$subDirName");
      subDir.create().then((ignore) {
        // Construct a long string of the form
        // 'tempdir/subdir/../subdir/../subdir'.
        var buffer = new StringBuffer();
        buffer.write(subDir.path);
        for (var i = 0; i < 1000; i++) {
          buffer.write("/../${subDirName}");
        }
        var long = new Directory("${buffer.toString()}");
        var errors = 0;
        onError(error) {
          Expect.isTrue(error is FileSystemException);
          if (++errors == 2) {
            d.delete(recursive: true).then((_) => asyncEnd());
          }
        }

        long.delete().catchError(onError);
        long.delete(recursive: true).catchError(onError);
      });
    });
  }

  static void testDeleteNonExistentSync() {
    Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
    d.deleteSync();
    Expect.throws(d.deleteSync);
    Expect.throws(() => d.deleteSync(recursive: true));
  }

  static void testDeleteTooLongNameSync() {
    Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
    var subDirName = 'subdir';
    var subDir = new Directory("${d.path}/$subDirName");
    subDir.createSync();
    // Construct a long string of the form
    // 'tempdir/subdir/../subdir/../subdir'.
    var buffer = new StringBuffer();
    buffer.write(subDir.path);
    for (var i = 0; i < 1000; i++) {
      buffer.write("/../${subDirName}");
    }
    var long = new Directory("${buffer.toString()}");
    Expect.throws(long.deleteSync);
    Expect.throws(() => long.deleteSync(recursive: true));
    d.deleteSync(recursive: true);
  }

  static void testExistsCreateDelete() {
    Directory.systemTemp.createTemp('dart_directory').then((d) {
      d.exists().then((bool exists) {
        Expect.isTrue(exists);
        Directory created = new Directory("${d.path}/subdir");
        created.create().then((ignore) {
          created.exists().then((bool exists) {
            Expect.isTrue(exists);
            created.delete().then((ignore) {
              created.exists().then((bool exists) {
                Expect.isFalse(exists);
                d.delete().then((ignore) {
                  d.exists().then((bool exists) {
                    Expect.isFalse(exists);
                  });
                });
              });
            });
          });
        });
      });
    });
  }

  static void testExistsCreateDeleteSync() {
    Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
    Directory d2 = new Directory('${d.path}/');
    Expect.isTrue(d.existsSync());
    Expect.isTrue(d2.existsSync());
    Directory created = new Directory("${d.path}/subdir");
    created.createSync();
    Expect.isTrue(created.existsSync());
    created.deleteSync();
    Expect.isFalse(created.existsSync());
    d.deleteSync();
    Expect.isFalse(d.existsSync());
  }

  static void testDeleteLinkSync() {
    Directory tmp = Directory.systemTemp.createTempSync('dart_directory_test');
    var path = "${tmp.path}${Platform.pathSeparator}";
    Directory d = new Directory("${path}target");
    d.createSync();
    Link l = new Link("${path}symlink");
    l.createSync("${path}target");
    Expect.isTrue(d.existsSync());
    Expect.isTrue(l.existsSync());
    new Directory(l.path).deleteSync(recursive: true);
    Expect.isTrue(d.existsSync());
    Expect.isFalse(l.existsSync());
    d.deleteSync();
    Expect.isFalse(d.existsSync());
    tmp.deleteSync();
  }

  static void testDeleteLinkAsFileSync() {
    Directory tmp = Directory.systemTemp.createTempSync('dart_directory_test');
    var path = "${tmp.path}${Platform.pathSeparator}";
    Directory d = new Directory("${path}target");
    d.createSync();
    Link l = new Link("${path}symlink");
    l.createSync("${path}target");
    Expect.isTrue(d.existsSync());
    Expect.isTrue(l.existsSync());
    new Link(l.path).deleteSync();
    Expect.isTrue(d.existsSync());
    Expect.isFalse(l.existsSync());
    d.deleteSync();
    Expect.isFalse(d.existsSync());
    tmp.deleteSync();
  }

  static void testDeleteBrokenLinkAsFileSync() {
    Directory tmp = Directory.systemTemp.createTempSync('dart_directory_test');
    var path = "${tmp.path}${Platform.pathSeparator}";
    Directory d = new Directory("${path}target");
    d.createSync();
    Link l = new Link("${path}symlink");
    l.createSync("${path}target");
    d.deleteSync();
    Expect.isFalse(d.existsSync());
    Expect.isTrue(l.existsSync());
    new Link(l.path).deleteSync();
    Expect.isFalse(l.existsSync());
    Expect.isFalse(d.existsSync());
    tmp.deleteSync();
  }

  static void testListBrokenLinkSync() {
    Directory tmp = Directory.systemTemp.createTempSync('dart_directory_test');
    var path = "${tmp.path}${Platform.pathSeparator}";
    Directory d = new Directory("${path}target");
    d.createSync();
    Link l = new Link("${path}symlink");
    l.createSync("${path}target");
    d.deleteSync();
    int count = 0;
    tmp.list(followLinks: true).listen((file) {
      count++;
      Expect.isTrue(file is Link);
    }, onDone: () {
      Expect.equals(1, count);
      l.deleteSync();
      tmp.deleteSync();
    });
  }

  static void testListLinkSync() {
    Directory tmp = Directory.systemTemp.createTempSync('dart_directory_test');
    var path = "${tmp.path}${Platform.pathSeparator}";
    Directory d = new Directory("${path}target");
    d.createSync();
    Link l = new Link("${path}symlink");
    l.createSync("${path}target");
    int count = 0;
    tmp.list(followLinks: true).listen((file) {
      count++;
      Expect.isTrue(file is Directory);
    }, onDone: () {
      Expect.equals(2, count);
      l.deleteSync();
      d.deleteSync();
      tmp.deleteSync();
    });
  }

  static void testCreateTemp() {
    Directory base = new Directory('/tmp');
    String template = 'dart_temp_dir';
    if (base.existsSync()) {
      asyncStart();
      Future.wait([base.createTemp(template), base.createTemp(template)])
          .then((tempDirs) {
        Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
        for (Directory t in tempDirs) {
          Expect.isTrue(t.existsSync());
          t.deleteSync();
          Expect.isFalse(t.existsSync());
        }
        asyncEnd();
      });
    }
  }

  static void testCreateSystemTemp() {
    String template = 'dart_system_temp_dir';
    asyncStart();
    Future.wait([
      Directory.systemTemp.createTemp(template),
      Directory.systemTemp.createTemp(template)
    ]).then((tempDirs) {
      Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
      for (Directory t in tempDirs) {
        Expect.isTrue(t.existsSync());
        t.deleteSync();
        Expect.isFalse(t.existsSync());
      }
      asyncEnd();
    });
  }

  static void testCreateDeleteTemp() {
    Directory.systemTemp.createTemp('dart_directory').then((tempDirectory) {
      String filename =
          "${tempDirectory.path}${Platform.pathSeparator}dart_testfile";
      File file = new File(filename);
      Expect.isFalse(file.existsSync());
      file.create().then((ignore) {
        file.exists().then((exists) {
          Expect.isTrue(exists);
          // Try to delete the directory containing the file - should throw.
          Expect.throws(tempDirectory.deleteSync);
          Expect.isTrue(tempDirectory.existsSync());

          // Delete the file, and then delete the directory.
          file.delete().then((ignore) {
            tempDirectory.deleteSync();
            Expect.isFalse(tempDirectory.existsSync());
          });
        });
      });
    });
  }

  static void testCurrent() {
    Directory current = Directory.current;
    if (Platform.operatingSystem != "windows") {
      Expect.equals("/", current.path.substring(0, 1));
    }
  }

  static void testEquals() {
    var name = new File('.').resolveSymbolicLinksSync();
    Directory current1 = new Directory(name);
    Directory current2 = new Directory(name);
    Expect.equals(current1.path, current2.path);
    Expect.isTrue(current1.existsSync());
  }

  static void testMain() {
    testListing();
    testListingTailingPaths();
    testListNonExistent();
    testListTooLongName();
    testDeleteNonExistent();
    testDeleteTooLongName();
    testDeleteNonExistentSync();
    testDeleteTooLongNameSync();
    testExistsCreateDelete();
    testExistsCreateDeleteSync();
    testDeleteLinkSync();
    testDeleteLinkAsFileSync();
    testDeleteBrokenLinkAsFileSync();
    testListBrokenLinkSync();
    testListLinkSync();
    testCreateTemp();
    testCreateSystemTemp();
    testCreateDeleteTemp();
    testCurrent();
    testEquals();
  }
}

class NestedTempDirectoryTest {
  List<Directory> createdDirectories;
  Directory current;

  NestedTempDirectoryTest.run() : createdDirectories = new List<Directory>() {
    Directory.systemTemp.createTemp('dart_directory').then(createPhaseCallback);
  }

  void createPhaseCallback(temp) {
    createdDirectories.add(temp);
    int nestingDepth = 6;
    var os = Platform.operatingSystem;
    if (os == "windows") nestingDepth = 2;
    if (createdDirectories.length < nestingDepth) {
      temp
          .createTemp('nested_temp_dir_${createdDirectories.length}_')
          .then(createPhaseCallback);
    } else {
      deletePhaseCallback();
    }
  }

  void deletePhaseCallback() {
    if (!createdDirectories.isEmpty) {
      current = createdDirectories.removeLast();
      current.deleteSync();
      deletePhaseCallback();
    }
  }

  static void testMain() {
    new NestedTempDirectoryTest.run();
    new NestedTempDirectoryTest.run();
  }
}

String illegalTempDirectoryLocation() {
  // Determine a platform specific illegal location for a temporary directory.
  var os = Platform.operatingSystem;
  if (os == "linux" || os == "macos") {
    return "/dev/zero/";
  }
  if (os == "windows") {
    return "*";
  }
  return null;
}

testCreateTempErrorSync() {
  var location = illegalTempDirectoryLocation();
  if (location != null) {
    Expect.throws(() => new Directory(location).createTempSync('dart_tempdir'),
        (e) => e is FileSystemException);
  }
}

testCreateTempError() {
  var location = illegalTempDirectoryLocation();
  if (location == null) return;

  asyncStart();
  var future = new Directory(location).createTemp('dart_tempdir');
  future.catchError((_) => asyncEnd());
}

testCreateExistingSync() {
  // Test that creating an existing directory succeeds.
  var temp = Directory.systemTemp.createTempSync('directory_test');
  var subDir = new Directory('${temp.path}/flaf');
  Expect.isFalse(subDir.existsSync());
  subDir.createSync();
  Expect.isTrue(subDir.existsSync());
  subDir.createSync();
  Expect.isTrue(subDir.existsSync());
  temp.deleteSync(recursive: true);
}

testCreateExisting() {
  // Test that creating an existing directory succeeds.
  asyncStart();
  Directory.systemTemp.createTemp('dart_directory').then((temp) {
    var subDir = new Directory('${temp.path}/flaf');
    subDir.exists().then((dirExists) {
      Expect.isFalse(dirExists);
      subDir.create().then((_) {
        subDir.exists().then((dirExists) {
          Expect.isTrue(dirExists);
          subDir.create().then((_) {
            subDir.exists().then((dirExists) {
              Expect.isTrue(dirExists);
              temp.delete(recursive: true).then((_) {
                asyncEnd();
              });
            });
          });
        });
      });
    });
  });
}

testCreateDirExistingFileSync() {
  // Test that creating an existing directory succeeds.
  var temp = Directory.systemTemp.createTempSync('directory_test');
  var path = '${temp.path}/flaf';
  var file = new File(path);
  file.createSync();
  Expect.isTrue(file.existsSync());
  Expect.throws(
      new Directory(path).createSync, (e) => e is FileSystemException);
  temp.deleteSync(recursive: true);
}

testCreateDirExistingFile() {
  // Test that creating an existing directory succeeds.
  asyncStart();
  Directory.systemTemp.createTemp('dart_directory').then((temp) {
    var path = '${temp.path}/flaf';
    var file = new File(path);
    var subDir = new Directory(path);
    file.create().then((_) {
      subDir.create().then((_) {
        Expect.fail("dir create should fail on existing file");
      }).catchError((error) {
        Expect.isTrue(error is FileSystemException);
        temp.delete(recursive: true).then((_) {
          asyncEnd();
        });
      });
    });
  });
}

testRename() {
  var temp1 = Directory.systemTemp.createTempSync('directory_test');
  var temp2 = Directory.systemTemp.createTempSync('directory_test');
  var temp3 = temp1.renameSync(temp2.path);
  Expect.isFalse(temp1.existsSync());
  Expect.isTrue(temp2.existsSync());
  Expect.equals(temp3.path, temp2.path);

  var temp4 = temp2.renameSync(temp1.path);
  Expect.isFalse(temp3.existsSync());
  Expect.isFalse(temp2.existsSync());
  Expect.isTrue(temp1.existsSync());
  Expect.isTrue(temp4.existsSync());
  Expect.equals(temp1.path, temp4.path);

  String foo = '${temp4.path}/foo';
  String bar = '${temp4.path}/bar';
  new File(foo).createSync();
  try {
    new Directory(foo).renameSync(bar);
    Expect.fail('Directory.rename should fail to rename a non-directory');
  } catch (e) {
    Expect.isTrue(e is FileSystemException);
    if (Platform.isLinux || Platform.isMacOS) {
      Expect.isTrue(e.osError.message.contains('Not a directory'));
    }
  }

  temp1.deleteSync(recursive: true);
}

main() {
  DirectoryTest.testMain();
  NestedTempDirectoryTest.testMain();
  testCreateTempErrorSync();
  testCreateTempError();
  testCreateExistingSync();
  testCreateExisting();
  testCreateDirExistingFileSync();
  testCreateDirExistingFile();
  testRename();
}
