// Copyright (c) 2013, 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.
//
// Dart test program for testing FileSystemEntity.resolveSymbolicLinks

import "package:expect/expect.dart";
import "package:path/path.dart";
import "package:async_helper/async_helper.dart";
import 'dart:async';
import 'dart:io';

main() {
  String testsDir = Directory.current.uri.resolve('tests').toFilePath();

  // All of these tests test that resolveSymbolicLinks gives a path
  // that points to the same place as the original, and that it removes
  // all links, .., and . segments, and that it produces an absolute path.
  asyncTest(() => testFile(
      join(testsDir, 'standalone', 'io', 'resolve_symbolic_links_test.dart')));
  asyncTest(() => testFile(join(testsDir, 'standalone', 'io', '..', 'io',
      'resolve_symbolic_links_test.dart')));

  asyncTest(() => testDir(join(testsDir, 'standalone', 'io')));
  asyncTest(() => testDir(join(testsDir, 'lib_2', '..', 'standalone', 'io')));
  // Test a relative path.
  if (Platform.isWindows) {
    asyncTest(() => testFile(join('\\\\?\\$testsDir', 'standalone', 'io',
        'resolve_symbolic_links_test.dart')));
    asyncTest(() => testDir('\\\\?\\$testsDir'));
  }
  asyncTest(() => Directory.systemTemp
          .createTemp('dart_resolve_symbolic_links')
          .then((tempDir) {
        String temp = tempDir.path;
        return makeEntities(temp)
            .then((_) => Future.wait([
                  testFile(join(temp, 'dir1', 'file1')),
                  testFile(join(temp, 'link1', 'file2')),
                  testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
                  testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
                  testLink(join(temp, 'link1')),
                  testDir('.')
                ]))
            .then((_) {
          if (Platform.isWindows) {
            // Windows applies '..' to a link without resolving the link first.
            return Future.wait([
              testFile(join(
                  temp, 'dir1', '..', 'link1', '..', 'dir1', 'dir2', 'file2')),
              testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir1')),
              testLink(join(temp, 'link1', '..', 'link1'))
            ]);
          } else {
            // Non-Windows platforms resolve the link before adding the '..'.
            return Future.wait([
              testFile(
                  join(temp, 'dir1', '..', 'link1', '..', 'dir2', 'file2')),
              testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir2')),
              testLink(join(temp, 'link1', '..', '..', 'link1'))
            ]);
          }
        }).then((_) {
          Directory.current = temp;
          return Future.wait([
            testFile('dir1/dir2/file2'), // Test forward slashes on Windows too.
            testFile('link1/file2'),
            testFile(join('dir1', '..', 'dir1', '.', 'file1')),
            testDir('.'),
            testLink('link1')
          ]);
        }).then((_) {
          Directory.current = 'link1';
          if (Platform.isWindows) {
            return Future.wait([
              testFile('file2'),
              // Windows applies '..' to a link without resolving the link first.
              testFile('..\\dir1\\file1'),
              testLink('.'),
              testDir('..'),
              testLink('..\\link1')
            ]);
          } else {
            return Future.wait([
              testFile('file2'),
              // On non-Windows the link is changed to dir1/dir2 before .. happens.
              testFile('../dir2/file2'),
              testDir('.'),
              testDir('..'),
              testLink('../../link1')
            ]);
          }
        }).whenComplete(() {
          Directory.current = testsDir;
          tempDir.delete(recursive: true);
        });
      }));
}

Future makeEntities(String temp) {
  return new Directory(join(temp, 'dir1', 'dir2'))
      .create(recursive: true)
      .then((_) => new File(join(temp, 'dir1', 'dir2', 'file2')).create())
      .then((_) => new File(join(temp, 'dir1', 'file1')).create())
      .then((_) =>
          new Link(join(temp, 'link1')).create(join(temp, 'dir1', 'dir2')));
}

Future testFile(String name) {
  // We test that f.resolveSymbolicLinks points to the same place
  // as f, because the actual resolved path is not easily predictable.
  // The location of the temp directory varies from system to system,
  // and its path includes symbolic links on some systems.
  //Expect.isTrue(FileSystemEntity.identicalSync(name,
  //   new File(name).resolveSymbolicLinksSync()));
  return new File(name).resolveSymbolicLinks().then((String resolved) {
    //Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
    Expect.isTrue(isAbsolute(resolved));
    // Test that resolveSymbolicLinks removes all links, .., and . segments.
    Expect.isFalse(resolved.contains('..'));
    Expect.isFalse(resolved.contains('./'));
    Expect.isFalse(resolved.contains('link1'));
  });
}

Future testDir(String name) {
  Expect.isTrue(FileSystemEntity.identicalSync(
      name, new Directory(name).resolveSymbolicLinksSync()));
  return new Directory(name).resolveSymbolicLinks().then((String resolved) {
    Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
    Expect.isTrue(isAbsolute(resolved));
    // Test that resolveSymbolicLinks removes all links, .., and . segments.
    Expect.isFalse(resolved.contains('..'));
    Expect.isFalse(resolved.contains('./'));
    Expect.isFalse(resolved.contains('link1'));
  });
}

Future testLink(String name) {
  Expect.isFalse(FileSystemEntity.identicalSync(
      name, new Link(name).resolveSymbolicLinksSync()));
  Expect.isTrue(FileSystemEntity.identicalSync(
      new Link(name).targetSync(), new Link(name).resolveSymbolicLinksSync()));
  return new Link(name).resolveSymbolicLinks().then((String resolved) {
    Expect.isFalse(FileSystemEntity.identicalSync(name, resolved));
    Expect.isTrue(isAbsolute(resolved));
    // Test that resolveSymbolicLinks removes all links, .., and . segments.
    Expect.isFalse(resolved.contains('..'));
    Expect.isFalse(resolved.contains('./'));
    Expect.isFalse(resolved.contains('link1'));
    return new Link(name)
        .target()
        .then((targetName) => FileSystemEntity.identical(targetName, resolved))
        .then((identical) => Expect.isTrue(identical));
  });
}
