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

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:pub/src/exceptions.dart';
import 'package:pub/src/io.dart';
import 'package:pub/src/third_party/tar/lib/tar.dart';
import 'package:test/test.dart';

import 'descriptor.dart' as d;
import 'test_pub.dart';

void main() {
  group('process', () {
    final nonExisting =
        path.join(path.dirname(Platform.resolvedExecutable), 'gone');
    test('Nice error message when failing to start process.', () {
      final throwsNiceErrorMessage = throwsA(
        predicate(
          (e) =>
              e is ApplicationException &&
              e.message.contains(
                'Pub failed to run subprocess `$nonExisting`: ProcessException:',
              ),
        ),
      );

      expect(
        () => runProcess(nonExisting, ['a', 'b', 'c']),
        throwsNiceErrorMessage,
      );
      expect(
        () => startProcess(nonExisting, ['a', 'b', 'c']),
        throwsNiceErrorMessage,
      );
      expect(
        () => runProcessSync(nonExisting, ['a', 'b', 'c']),
        throwsNiceErrorMessage,
      );
    });
  });
  group('listDir', () {
    test('ignores hidden files by default', () {
      expect(
        withTempDir((temp) {
          writeTextFile(path.join(temp, 'file1.txt'), '');
          writeTextFile(path.join(temp, 'file2.txt'), '');
          writeTextFile(path.join(temp, '.file3.txt'), '');
          _createDir(path.join(temp, '.subdir'));
          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');

          expect(
            listDir(temp, recursive: true),
            unorderedEquals(
              [path.join(temp, 'file1.txt'), path.join(temp, 'file2.txt')],
            ),
          );
        }),
        completes,
      );
    });

    test('includes hidden files when told to', () {
      expect(
        withTempDir((temp) {
          writeTextFile(path.join(temp, 'file1.txt'), '');
          writeTextFile(path.join(temp, 'file2.txt'), '');
          writeTextFile(path.join(temp, '.file3.txt'), '');
          _createDir(path.join(temp, '.subdir'));
          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');

          expect(
            listDir(temp, recursive: true, includeHidden: true),
            unorderedEquals([
              path.join(temp, 'file1.txt'),
              path.join(temp, 'file2.txt'),
              path.join(temp, '.file3.txt'),
              path.join(temp, '.subdir'),
              path.join(temp, '.subdir', 'file3.txt')
            ]),
          );
        }),
        completes,
      );
    });

    test("doesn't ignore hidden files above the directory being listed", () {
      expect(
        withTempDir((temp) {
          var dir = path.join(temp, '.foo', 'bar');
          ensureDir(dir);
          writeTextFile(path.join(dir, 'file1.txt'), '');
          writeTextFile(path.join(dir, 'file2.txt'), '');
          writeTextFile(path.join(dir, 'file3.txt'), '');

          expect(
            listDir(dir, recursive: true),
            unorderedEquals([
              path.join(dir, 'file1.txt'),
              path.join(dir, 'file2.txt'),
              path.join(dir, 'file3.txt')
            ]),
          );
        }),
        completes,
      );
    });
  });

  group('canonicalize', () {
    test('resolves a non-link', () {
      expect(
        _withCanonicalTempDir((temp) {
          var filePath = path.join(temp, 'file');
          writeTextFile(filePath, '');
          expect(canonicalize(filePath), equals(filePath));
        }),
        completes,
      );
    });

    test('resolves a non-existent file', () {
      expect(
        _withCanonicalTempDir((temp) {
          expect(
            canonicalize(path.join(temp, 'nothing')),
            equals(path.join(temp, 'nothing')),
          );
        }),
        completes,
      );
    });

    test('resolves a symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          _createDir(path.join(temp, 'linked-dir'));
          createSymlink(path.join(temp, 'linked-dir'), path.join(temp, 'dir'));
          expect(
            canonicalize(path.join(temp, 'dir')),
            equals(path.join(temp, 'linked-dir')),
          );
        }),
        completes,
      );
    });

    test('resolves a relative symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          _createDir(path.join(temp, 'linked-dir'));
          createSymlink(
            path.join(temp, 'linked-dir'),
            path.join(temp, 'dir'),
            relative: true,
          );
          expect(
            canonicalize(path.join(temp, 'dir')),
            equals(path.join(temp, 'linked-dir')),
          );
        }),
        completes,
      );
    });

    test('resolves a single-level horizontally recursive symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          var linkPath = path.join(temp, 'foo');
          createSymlink(linkPath, linkPath);
          expect(canonicalize(linkPath), equals(linkPath));
        }),
        completes,
      );
    });

    test('resolves a multi-level horizontally recursive symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          var fooPath = path.join(temp, 'foo');
          var barPath = path.join(temp, 'bar');
          var bazPath = path.join(temp, 'baz');
          createSymlink(barPath, fooPath);
          createSymlink(bazPath, barPath);
          createSymlink(fooPath, bazPath);
          expect(canonicalize(fooPath), equals(fooPath));
          expect(canonicalize(barPath), equals(barPath));
          expect(canonicalize(bazPath), equals(bazPath));

          createSymlink(fooPath, path.join(temp, 'outer'));
          expect(canonicalize(path.join(temp, 'outer')), equals(fooPath));
        }),
        completes,
      );
    });

    test('resolves a broken symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          createSymlink(path.join(temp, 'nonexistent'), path.join(temp, 'foo'));
          expect(
            canonicalize(path.join(temp, 'foo')),
            equals(path.join(temp, 'nonexistent')),
          );
        }),
        completes,
      );
    });

    test('resolves multiple nested symlinks', () {
      expect(
        _withCanonicalTempDir((temp) {
          var dir1 = path.join(temp, 'dir1');
          var dir2 = path.join(temp, 'dir2');
          var subdir1 = path.join(dir1, 'subdir1');
          var subdir2 = path.join(dir2, 'subdir2');
          _createDir(dir2);
          _createDir(subdir2);
          createSymlink(dir2, dir1);
          createSymlink(subdir2, subdir1);
          expect(
            canonicalize(path.join(subdir1, 'file')),
            equals(path.join(subdir2, 'file')),
          );
        }),
        completes,
      );
    });

    test('resolves a nested vertical symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          var dir1 = path.join(temp, 'dir1');
          var dir2 = path.join(temp, 'dir2');
          var subdir = path.join(dir1, 'subdir');
          _createDir(dir1);
          _createDir(dir2);
          createSymlink(dir2, subdir);
          expect(
            canonicalize(path.join(subdir, 'file')),
            equals(path.join(dir2, 'file')),
          );
        }),
        completes,
      );
    });

    test('resolves a vertically recursive symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          var dir = path.join(temp, 'dir');
          var subdir = path.join(dir, 'subdir');
          _createDir(dir);
          createSymlink(dir, subdir);
          expect(
            canonicalize(
              path.join(
                temp,
                'dir',
                'subdir',
                'subdir',
                'subdir',
                'subdir',
                'file',
              ),
            ),
            equals(path.join(dir, 'file')),
          );
        }),
        completes,
      );
    });

    test('resolves a symlink that links to a path that needs more resolving',
        () {
      expect(
        _withCanonicalTempDir((temp) {
          var dir = path.join(temp, 'dir');
          var linkdir = path.join(temp, 'linkdir');
          var linkfile = path.join(dir, 'link');
          _createDir(dir);
          createSymlink(dir, linkdir);
          createSymlink(path.join(linkdir, 'file'), linkfile);
          expect(canonicalize(linkfile), equals(path.join(dir, 'file')));
        }),
        completes,
      );
    });

    test('resolves a pair of pathologically-recursive symlinks', () {
      expect(
        _withCanonicalTempDir((temp) {
          var foo = path.join(temp, 'foo');
          var subfoo = path.join(foo, 'subfoo');
          var bar = path.join(temp, 'bar');
          var subbar = path.join(bar, 'subbar');
          createSymlink(subbar, foo);
          createSymlink(subfoo, bar);
          expect(
            canonicalize(subfoo),
            equals(path.join(subfoo, 'subbar', 'subfoo')),
          );
        }),
        completes,
      );
    });
  });

  group('extractTarGz', () {
    test('decompresses simple archive', () async {
      await withTempDir((tempDir) async {
        await extractTarGz(
          Stream.fromIterable(
            [
              base64Decode(
                  'H4sIAP2weF4AA+3S0QqCMBiG4V2KeAE1nfuF7maViNBqzDyQ6N4z6yCIogOtg97ncAz2wTvfuxCW'
                  'alZ6UFqttIiUYpXObWlzM57fqcyIkcxoU2ZKZyYvtErsvLNuuvboYpKotqm7uPUv74XYeBf7Oh66'
                  '8I1dX+LH/qFbt6HaLHrnd9O/cQ0sxZv++UP/Qob+1srQX08/5dmf9z+le+erdJWOHyE9/3oPAAAA'
                  'AAAAAAAAAAAAgM9dALkoaRMAKAAA')
            ],
          ),
          tempDir,
        );

        await d.dir(appPath, [
          d.rawPubspec({
            'name': 'myapp',
          }),
        ]).validate(tempDir);
      });
    });

    test('throws on tar error', () async {
      await withTempDir((tempDir) async {
        await expectLater(
          () async => await extractTarGz(
            Stream.fromIterable(
              [
                base64Decode(
                    // Correct Gzip of a faulty tar archive.
                    'H4sICBKyeF4AA215YXBwLnRhcgDt0sEKgjAAh/GdewrxAWpzbkJvs0pEaDVmHiR699Q6BBJ00Dr0'
                    '/Y5jsD98850LYSMWJXuFkUJaITNTmEyPR09Caaut0lIXSkils1yKxCy76KFtLi4miWjqqo0H//Ze'
                    'iLV3saviuQ3f2PUlfkwf2l0Tyv26c/44/xtDYJsP6a0trJn2z1765/3/UMbYvr+cf8rUn/e/pifn'
                    'y3Sbjh8hvf16DwAAAAAAAAAAAAAAAIDPre4CU/3q/CcAAA==')
              ],
            ),
            tempDir,
          ),
          throwsA(isA<TarException>()),
        );
      });
    });

    test('throws on gzip error', () async {
      await withTempDir((tempDir) async {
        await expectLater(
          () async => await extractTarGz(
            Stream.fromIterable(
              [
                [10, 20, 30] // Not a good gz stream.
              ],
            ),
            tempDir,
          ),
          throwsA(
            isA<FormatException>().having(
              (e) => e.message,
              'message',
              contains('Filter error, bad data'),
            ),
          ),
        );
      });
    });

    test(
      'applies executable bits from tar file',
      () => withTempDir((tempDir) async {
        final entry = Stream<TarEntry>.value(
          TarEntry.data(
            TarHeader(
              name: 'weird_exe',
              typeFlag: TypeFlag.reg,
              mode: int.parse('110', radix: 8),
            ),
            const [],
          ),
        );

        await extractTarGz(
          entry.transform(tarWriter).transform(gzip.encoder),
          tempDir,
        );

        expect(File('$tempDir/weird_exe').statSync().modeString(), 'rwxr-xr--');
      }),
      testOn: 'linux || mac-os',
    );

    test('extracts files and links', () {
      return withTempDir((tempDir) async {
        final entries = Stream<TarEntry>.fromIterable([
          TarEntry.data(
            TarHeader(name: 'lib/main.txt', typeFlag: TypeFlag.reg),
            utf8.encode('text content'),
          ),
          TarEntry.data(
            TarHeader(
              name: 'bin/main.txt',
              typeFlag: TypeFlag.symlink,
              linkName: '../lib/main.txt',
            ),
            const [],
          ),
          TarEntry.data(
            TarHeader(
              name: 'test/main.txt',
              typeFlag: TypeFlag.link,
              // TypeFlag.link is resolved against the root of the tar file
              linkName: 'lib/main.txt',
            ),
            const [],
          ),
        ]);

        await extractTarGz(
          entries.transform(tarWriter).transform(gzip.encoder),
          tempDir,
        );

        await d.dir(
          '.',
          [
            d.file('lib/main.txt', 'text content'),
            d.file('bin/main.txt', 'text content'),
            d.file('test/main.txt', 'text content'),
          ],
        ).validate(tempDir);
      });
    });

    test('preserves empty directories', () {
      return withTempDir((tempDir) async {
        final entry = Stream<TarEntry>.value(
          TarEntry.data(
            TarHeader(
              name: 'bin/',
              typeFlag: TypeFlag.dir,
            ),
            const [],
          ),
        );

        await extractTarGz(
          entry.transform(tarWriter).transform(gzip.encoder),
          tempDir,
        );

        await expectLater(
          Directory(tempDir).list(),
          emits(
            isA<Directory>()
                .having((e) => path.basename(e.path), 'basename', 'bin'),
          ),
        );
      });
    });

    test('throws for entries escaping the tar file', () {
      return withTempDir((tempDir) async {
        final entry = Stream<TarEntry>.value(
          TarEntry.data(
            TarHeader(
              name: '../other_package-1.2.3/lib/file.dart',
              typeFlag: TypeFlag.reg,
            ),
            const [],
          ),
        );

        await expectLater(
          extractTarGz(
            entry.transform(tarWriter).transform(gzip.encoder),
            tempDir,
          ),
          throwsA(isA<FormatException>()),
        );

        await expectLater(Directory(tempDir).list(), emitsDone);
      });
    });

    test('skips symlinks escaping the tar file', () {
      return withTempDir((tempDir) async {
        final entry = Stream<TarEntry>.value(
          TarEntry.data(
            TarHeader(
              name: 'nested/bad_link',
              typeFlag: TypeFlag.symlink,
              linkName: '../../outside.txt',
            ),
            const [],
          ),
        );

        await extractTarGz(
          entry.transform(tarWriter).transform(gzip.encoder),
          tempDir,
        );

        await expectLater(Directory(tempDir).list(), emitsDone);
      });
    });

    test('skips hardlinks escaping the tar file', () {
      return withTempDir((tempDir) async {
        final entry = Stream<TarEntry>.value(
          TarEntry.data(
            TarHeader(
              name: 'nested/bad_link',
              typeFlag: TypeFlag.link,
              linkName: '../outside.txt',
            ),
            const [],
          ),
        );

        await extractTarGz(
          entry.transform(tarWriter).transform(gzip.encoder),
          tempDir,
        );

        await expectLater(Directory(tempDir).list(), emitsDone);
      });
    });
  });

  testExistencePredicate(
    'entryExists',
    entryExists,
    forFile: true,
    forFileSymlink: true,
    forMultiLevelFileSymlink: true,
    forDirectory: true,
    forDirectorySymlink: true,
    forMultiLevelDirectorySymlink: true,
    forBrokenSymlink: true,
    forMultiLevelBrokenSymlink: true,
  );

  testExistencePredicate(
    'linkExists',
    linkExists,
    forFile: false,
    forFileSymlink: true,
    forMultiLevelFileSymlink: true,
    forDirectory: false,
    forDirectorySymlink: true,
    forMultiLevelDirectorySymlink: true,
    forBrokenSymlink: true,
    forMultiLevelBrokenSymlink: true,
  );

  testExistencePredicate(
    'fileExists',
    fileExists,
    forFile: true,
    forFileSymlink: true,
    forMultiLevelFileSymlink: true,
    forDirectory: false,
    forDirectorySymlink: false,
    forMultiLevelDirectorySymlink: false,
    forBrokenSymlink: false,
    forMultiLevelBrokenSymlink: false,
  );

  testExistencePredicate(
    'dirExists',
    dirExists,
    forFile: false,
    forFileSymlink: false,
    forMultiLevelFileSymlink: false,
    forDirectory: true,
    forDirectorySymlink: true,
    forMultiLevelDirectorySymlink: true,
    forBrokenSymlink: false,
    forMultiLevelBrokenSymlink: false,
  );
}

void testExistencePredicate(
  String name,
  bool Function(String path) predicate, {
  required bool forFile,
  required bool forFileSymlink,
  required bool forMultiLevelFileSymlink,
  required bool forDirectory,
  required bool forDirectorySymlink,
  required bool forMultiLevelDirectorySymlink,
  required bool forBrokenSymlink,
  required bool forMultiLevelBrokenSymlink,
}) {
  group(name, () {
    test('returns $forFile for a file', () {
      expect(
        withTempDir((temp) {
          var file = path.join(temp, 'test.txt');
          writeTextFile(file, 'contents');
          expect(predicate(file), equals(forFile));
        }),
        completes,
      );
    });

    test('returns $forDirectory for a directory', () {
      expect(
        withTempDir((temp) {
          var file = path.join(temp, 'dir');
          _createDir(file);
          expect(predicate(file), equals(forDirectory));
        }),
        completes,
      );
    });

    test('returns $forDirectorySymlink for a symlink to a directory', () {
      expect(
        withTempDir((temp) {
          var targetPath = path.join(temp, 'dir');
          var symlinkPath = path.join(temp, 'linkdir');
          _createDir(targetPath);
          createSymlink(targetPath, symlinkPath);
          expect(predicate(symlinkPath), equals(forDirectorySymlink));
        }),
        completes,
      );
    });

    test(
        'returns $forMultiLevelDirectorySymlink for a multi-level symlink to '
        'a directory', () {
      expect(
        withTempDir((temp) {
          var targetPath = path.join(temp, 'dir');
          var symlink1Path = path.join(temp, 'link1dir');
          var symlink2Path = path.join(temp, 'link2dir');
          _createDir(targetPath);
          createSymlink(targetPath, symlink1Path);
          createSymlink(symlink1Path, symlink2Path);
          expect(
            predicate(symlink2Path),
            equals(forMultiLevelDirectorySymlink),
          );
        }),
        completes,
      );
    });

    test('returns $forBrokenSymlink for a broken symlink', () {
      expect(
        withTempDir((temp) {
          var targetPath = path.join(temp, 'dir');
          var symlinkPath = path.join(temp, 'linkdir');
          _createDir(targetPath);
          createSymlink(targetPath, symlinkPath);
          deleteEntry(targetPath);
          expect(predicate(symlinkPath), equals(forBrokenSymlink));
        }),
        completes,
      );
    });

    test('returns $forMultiLevelBrokenSymlink for a multi-level broken symlink',
        () {
      expect(
        withTempDir((temp) {
          var targetPath = path.join(temp, 'dir');
          var symlink1Path = path.join(temp, 'link1dir');
          var symlink2Path = path.join(temp, 'link2dir');
          _createDir(targetPath);
          createSymlink(targetPath, symlink1Path);
          createSymlink(symlink1Path, symlink2Path);
          deleteEntry(targetPath);
          expect(predicate(symlink2Path), equals(forMultiLevelBrokenSymlink));
        }),
        completes,
      );
    });

    // Windows doesn't support symlinking to files.
    if (!Platform.isWindows) {
      test('returns $forFileSymlink for a symlink to a file', () {
        expect(
          withTempDir((temp) {
            var targetPath = path.join(temp, 'test.txt');
            var symlinkPath = path.join(temp, 'link.txt');
            writeTextFile(targetPath, 'contents');
            createSymlink(targetPath, symlinkPath);
            expect(predicate(symlinkPath), equals(forFileSymlink));
          }),
          completes,
        );
      });

      test(
          'returns $forMultiLevelFileSymlink for a multi-level symlink to a '
          'file', () {
        expect(
          withTempDir((temp) {
            var targetPath = path.join(temp, 'test.txt');
            var symlink1Path = path.join(temp, 'link1.txt');
            var symlink2Path = path.join(temp, 'link2.txt');
            writeTextFile(targetPath, 'contents');
            createSymlink(targetPath, symlink1Path);
            createSymlink(symlink1Path, symlink2Path);
            expect(predicate(symlink2Path), equals(forMultiLevelFileSymlink));
          }),
          completes,
        );
      });
    }
  });

  test('escapeShellArgument', () {
    expect(escapeShellArgument(r'abc'), r'abc');
    expect(escapeShellArgument(r'ab c'), r"'ab c'");
    expect(escapeShellArgument(r'ab\c'), r"'ab\\c'");
    expect(escapeShellArgument(r"ab\'c"), r"'ab\\'\''c'");
  });
}

/// Like [withTempDir], but canonicalizes the path before passing it to [fn].
Future<T> _withCanonicalTempDir<T>(FutureOr<T> Function(String path) fn) =>
    withTempDir((temp) => fn(canonicalize(temp)));

/// Creates a directory [dir].
String _createDir(String dir) {
  Directory(dir).createSync();
  return dir;
}
