// Copyright (c) 2021, 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 rename test.

import "dart:io";

import "package:expect/expect.dart";
import 'test_utils.dart' show withTempDir;

testRenameToNewPath() async {
  await withTempDir('testRenameToNewPath', (Directory tempDir) async {
    final dir1 = Directory("${tempDir.path}/dir1");
    dir1.createSync();

    dir1.renameSync("${tempDir.path}/dir2");
    Expect.isTrue(Directory("${tempDir.path}/dir2").existsSync());
  });
}

testRenameDoesNotAdjustPath() async {
  await withTempDir('testRenameToNewPath', (Directory tempDir) async {
    final dir1 = Directory("${tempDir.path}/dir1");
    dir1.createSync();
    final originalPath = dir1.path;

    dir1.renameSync("${tempDir.path}/dir2");
    final finalPath = dir1.path;
    Expect.isTrue(originalPath == finalPath,
        "$originalPath != $finalPath - path should not be updated");
  });
}

testRenameToSamePath() async {
  await withTempDir('testRenameToSamePath', (Directory tempDir) async {
    final dir = Directory("${tempDir.path}/dir");
    dir.createSync();
    final file = File("${dir.path}/file");
    file.createSync();

    try {
      dir.renameSync(dir.path);
      if (Platform.isWindows) {
        Expect.fail('Directory.rename to same path should fail on Windows');
      } else {
        Expect.isTrue(file.existsSync());
      }
    } on FileSystemException catch (e) {
      if (Platform.isWindows) {
        // On Windows, the directory will be *deleted*.
        Expect.isFalse(dir.existsSync());
        Expect.isTrue(
            e.osError!.message.contains('cannot find the file specified'),
            'Unexpected error: $e');
      } else {
        Expect.fail('Directory.rename to same path should not fail on '
            '${Platform.operatingSystem} (${Platform.operatingSystemVersion}): '
            '$e');
      }
    }
  });
}

testRenameToExistingFile() async {
  await withTempDir('testRenameToExistingFile', (Directory tempDir) async {
    final dir = Directory("${tempDir.path}/dir");
    dir.createSync();
    final file = File("${tempDir.path}/file");
    file.createSync();

    // Overwriting an exsting file is not allowed.
    try {
      dir.renameSync(file.path);
      Expect.fail('Directory.rename should fail to rename a non-directory');
    } on FileSystemException catch (e) {
      if (Platform.isLinux || Platform.isMacOS) {
        Expect.isTrue(e.osError!.message.contains('Not a directory'),
            'Unexpected error: $e');
      } else if (Platform.isWindows) {
        Expect.isTrue(e.osError!.message.contains('file already exists'),
            'Unexpected error: $e');
      }
    }
  });
}

testRenameToExistingEmptyDirectory() async {
  await withTempDir('testRenameToExistingEmptyDirectory',
      (Directory tempDir) async {
    final dir1 = Directory("${tempDir.path}/dir1");
    dir1.createSync();
    File("${dir1.path}/file").createSync();

    final dir2 = Directory("${tempDir.path}/dir2");
    dir2.createSync();

    dir1.renameSync(dir2.path);
    // Verify that the file contained in dir1 have been moved.
    Expect.isTrue(File("${dir2.path}/file").existsSync());
  });
}

testRenameToExistingNonEmptyDirectory() async {
  await withTempDir('testRenameToExistingNonEmptyDirectory',
      (Directory tempDir) async {
    final dir1 = Directory("${tempDir.path}/dir1");
    dir1.createSync();
    File("${dir1.path}/file1").createSync();

    final dir2 = Directory("${tempDir.path}/dir2");
    dir2.createSync();
    File("${dir2.path}/file2").createSync();

    try {
      dir1.renameSync(dir2.path);
      if (Platform.isWindows) {
        // Verify that the old directory is deleted.
        Expect.isTrue(File("${dir2.path}/file1").existsSync());
        Expect.isFalse(File("${dir2.path}/file2").existsSync());
      } else {
        Expect.fail(
            'Directory.rename should fail to rename a non-empty directory '
            'except on Windows');
      }
    } on FileSystemException catch (e) {
      if (Platform.isLinux || Platform.isMacOS) {
        Expect.isTrue(e.osError!.message.contains('Directory not empty'),
            'Unexpected error: $e');
      }
    }
  });
}

main() async {
  await testRenameToNewPath();
  await testRenameDoesNotAdjustPath();
  await testRenameToSamePath();
  await testRenameToExistingFile();
  await testRenameToExistingEmptyDirectory();
  await testRenameToExistingNonEmptyDirectory();
}
