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

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

  temp2.rename(temp1.path).then((temp4) {
    Expect.isFalse(temp3.existsSync());
    Expect.isFalse(temp2.existsSync());
    Expect.isTrue(temp1.existsSync());
    Expect.isTrue(temp4.existsSync());
    Expect.equals(temp1.path, temp4.path);
    temp1.deleteSync(recursive: true);
  });
}

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