// Copyright (c) 2020, 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:io';

import 'package:path/path.dart' as p;
import 'package:pub/src/exit_codes.dart' as exit_codes;
import 'package:test/test.dart';

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

Future<void> expectValidation(
  Matcher error,
  int exitCode, {
  Map<String, String> environment = const {},
  String? workingDirectory,
}) async {
  await runPub(
    error: error,
    args: ['publish', '--dry-run'],
    environment: environment,
    workingDirectory: workingDirectory ?? d.path(appPath),
    exitCode: exitCode,
  );
}

void main() {
  test(
      'should consider a package valid if it contains no checked in otherwise ignored files',
      () async {
    await d.git('myapp', [
      ...d.validPackage().contents,
      d.file('foo.txt'),
    ]).create();

    await expectValidation(contains('Package has 0 warnings.'), 0);

    await d.dir('myapp', [
      d.file('.gitignore', '*.txt'),
    ]).create();

    await expectValidation(
      allOf([
        contains('Package has 1 warning.'),
        contains('foo.txt'),
        contains(
          'Consider adjusting your `.gitignore` files to not ignore those files',
        ),
      ]),
      exit_codes.DATA,
    );
  });

  test('should not fail on missing git', () async {
    await d.git('myapp', [
      ...d.validPackage().contents,
      d.file('.gitignore', '*.txt'),
      d.file('foo.txt'),
    ]).create();

    await pubGet();
    await setUpFakeGitScript(bash: 'echo "Not git"', batch: 'echo "Not git"');
    await expectValidation(
      allOf([contains('Package has 0 warnings.')]),
      exit_codes.SUCCESS,
      environment: extendedPathEnv(),
    );
  });

  test('Should also consider gitignores from above the package root', () async {
    await d.git('reporoot', [
      d.dir(
        'myapp',
        [
          d.file('foo.txt'),
          ...d.validPackage().contents,
        ],
      ),
    ]).create();
    final packageRoot = p.join(d.sandbox, 'reporoot', 'myapp');
    await pubGet(workingDirectory: packageRoot);

    await expectValidation(
      contains('Package has 0 warnings.'),
      0,
      workingDirectory: packageRoot,
    );

    await d.dir('reporoot', [
      d.file('.gitignore', '*.txt'),
    ]).create();

    await expectValidation(
      allOf([
        contains('Package has 1 warning.'),
        contains('foo.txt'),
        contains(
          'Consider adjusting your `.gitignore` files to not ignore those files',
        ),
      ]),
      exit_codes.DATA,
      workingDirectory: packageRoot,
    );
  });

  test('Should not follow symlinks', () async {
    await d.git('myapp', [
      ...d.validPackage().contents,
    ]).create();
    final packageRoot = p.join(d.sandbox, 'myapp');
    await pubGet(workingDirectory: packageRoot);

    Link(p.join(packageRoot, '.abc', 'itself')).createSync(
      packageRoot,
      recursive: true,
    );

    await expectValidation(
      contains('Package has 0 warnings.'),
      0,
      workingDirectory: packageRoot,
    );
  });
}
