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

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

import '../git.dart' as git;
import '../ignore.dart';
import '../io.dart';
import '../log.dart' as log;
import '../path.dart';
import '../platform_info.dart';
import '../utils.dart';
import '../validator.dart';

/// A validator that validates that no checked in files are ignored by a
/// .gitignore. These would be considered part of the package by previous
/// versions of pub.
class GitignoreValidator extends Validator {
  @override
  Future<void> validate() async {
    if (package.inGitRepo) {
      final Uint8List output;
      try {
        output = git.runSyncBytes([
          '-c',
          'core.quotePath=false',
          'ls-files',
          '-z',
          '--cached',
          '--exclude-standard',
          '--recurse-submodules',
        ], workingDir: package.dir);
      } on git.GitException catch (e) {
        log.fine('Could not run `git ls-files` files in repo (${e.message}).');
        // This validation is only a warning.
        // If git is not supported on the platform, or too old to support
        // --recurse-submodules we just continue silently.
        return;
      }

      final List<String> checkedIntoGit;
      try {
        checkedIntoGit =
            git.splitZeroTerminated(output).map((b) {
              return utf8.decode(b);
            }).toList();
      } on FormatException catch (e) {
        log.fine('Failed decoding git output. Skipping validation. $e.');
        return;
      }
      final root = git.repoRoot(package.dir) ?? package.dir;
      var beneath = p.posix.joinAll(
        p.split(p.normalize(p.relative(package.dir, from: root))),
      );
      if (beneath == './') {
        beneath = '';
      }
      String resolve(String path) {
        if (platform.isWindows) {
          return p.joinAll([root, ...p.posix.split(path)]);
        }
        return p.join(root, path);
      }

      final unignoredByGitignore =
          Ignore.listFiles(
            beneath: beneath,
            listDir: (dir) {
              final contents = Directory(
                resolve(dir),
              ).listSync(followLinks: false);
              return contents.map(
                (entity) => p.posix.joinAll(
                  p.split(p.relative(entity.path, from: root)),
                ),
              );
            },
            ignoreForDir: (dir) {
              final gitIgnore = resolve('$dir/.gitignore');
              final rules = [
                if (fileExists(gitIgnore)) readTextFile(gitIgnore),
              ];
              return rules.isEmpty ? null : Ignore(rules);
            },
            isDir: (dir) {
              final resolved = resolve(dir);
              return dirExists(resolved) && !linkExists(resolved);
            },
          ).map((file) {
            final relative = p.relative(resolve(file), from: package.dir);
            return platform.isWindows
                ? p.posix.joinAll(p.split(relative))
                : relative;
          }).toSet();
      final ignoredFilesCheckedIn =
          checkedIntoGit
              .where((file) => !unignoredByGitignore.contains(file))
              .toList();

      if (ignoredFilesCheckedIn.isNotEmpty) {
        warnings.add('''
${ignoredFilesCheckedIn.length} checked-in ${pluralize('file', ignoredFilesCheckedIn.length)} ${ignoredFilesCheckedIn.length == 1 ? 'is' : 'are'} ignored by a `.gitignore`.
Previous versions of Pub would include those in the published package.

Consider adjusting your `.gitignore` files to not ignore those files, and if you do not wish to
publish these files use `.pubignore`. See also dart.dev/go/pubignore

Files that are checked in while gitignored:

${ignoredFilesCheckedIn.take(10).join('\n')}
${ignoredFilesCheckedIn.length > 10 ? '...' : ''}
''');
      }
    }
  }
}
