// 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 p;
import 'package:pub/src/exceptions.dart';
import 'package:pub/src/io.dart';
import 'package:tar/tar.dart';
import 'package:test/test.dart';

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

void main() {
  group('process', () {
    final nonExisting = p.join(p.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(p.join(temp, 'file1.txt'), '');
          writeTextFile(p.join(temp, 'file2.txt'), '');
          writeTextFile(p.join(temp, '.file3.txt'), '');
          _createDir(p.join(temp, '.subdir'));
          writeTextFile(p.join(temp, '.subdir', 'file3.txt'), '');

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

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

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

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

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

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

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

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

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

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

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

    test('resolves a multi-level horizontally recursive symlink', () {
      expect(
        _withCanonicalTempDir((temp) {
          final fooPath = p.join(temp, 'foo');
          final barPath = p.join(temp, 'bar');
          final bazPath = p.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, p.join(temp, 'outer'));
          expect(canonicalize(p.join(temp, 'outer')), equals(fooPath));
        }),
        completes,
      );
    });

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

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

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

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

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

    test('resolves a pair of pathologically-recursive symlinks', () {
      expect(
        _withCanonicalTempDir((temp) {
          final foo = p.join(temp, 'foo');
          final subfoo = p.join(foo, 'subfoo');
          final bar = p.join(temp, 'bar');
          final subbar = p.join(bar, 'subbar');
          createSymlink(subbar, foo);
          createSymlink(subfoo, bar);
          expect(
            canonicalize(subfoo),
            equals(p.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) => p.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) {
          final file = p.join(temp, 'test.txt');
          writeTextFile(file, 'contents');
          expect(predicate(file), equals(forFile));
        }),
        completes,
      );
    });

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

    test('returns $forDirectorySymlink for a symlink to a directory', () {
      expect(
        withTempDir((temp) {
          final targetPath = p.join(temp, 'dir');
          final symlinkPath = p.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) {
          final targetPath = p.join(temp, 'dir');
          final symlink1Path = p.join(temp, 'link1dir');
          final symlink2Path = p.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) {
          final targetPath = p.join(temp, 'dir');
          final symlinkPath = p.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) {
          final targetPath = p.join(temp, 'dir');
          final symlink1Path = p.join(temp, 'link1dir');
          final symlink2Path = p.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) {
            final targetPath = p.join(temp, 'test.txt');
            final symlinkPath = p.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) {
            final targetPath = p.join(temp, 'test.txt');
            final symlink1Path = p.join(temp, 'link1.txt');
            final symlink2Path = p.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;
}
