// Copyright (c) 2022, 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.

// Script to automatically update revisions in the DEPS file.
//
// Anyone can run this, and is welcome to.

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

import 'package:cli_util/cli_logging.dart';
import 'package:path/path.dart' as path;
import 'package:pool/pool.dart' as pool;

/// The following set of packages should be individually reviewed.
///
/// Generally, they are from repos that are not Dart team owned, and we want to
/// ensure that we consistently review all changes from those repos.
const Set<String> individuallyReviewedPackages = {
  'tar',
};

void main(List<String> args) async {
  // Validate we're running from the repo root.
  if (!File('README.dart-sdk').existsSync() || !File('DEPS').existsSync()) {
    stderr.writeln('Please run this script from the root of the SDK repo.');
    exit(1);
  }

  final gclient = GClientHelper();

  final deps = await gclient.getPackageDependencies();
  print('${deps.length} package dependencies found.');

  // Remove pinned deps.
  final pinnedDeps = calculatePinnedDeps();
  deps.removeWhere((dep) => pinnedDeps.contains(dep.name));

  print('Not attempting to move forward the revisions for: '
      '${pinnedDeps.toList().join(', ')}.');
  print('');

  deps.sort((a, b) => a.name.compareTo(b.name));

  final gitPool = pool.Pool(10);

  final revDepsToCommits = Map.fromEntries(
    (await Future.wait(
      deps.map((dep) {
        return gitPool.withResource(() async {
          final git = GitHelper(dep.relativePath);
          await git.fetch();
          var commit = await git.findLatestUnsyncedCommit();
          return MapEntry(dep, commit);
        });
      }),
    ))
        .where((entry) {
      final commit = entry.value;
      return commit.isNotEmpty;
    }),
  );

  if (revDepsToCommits.isEmpty) {
    print('No new revisions.');
    return;
  }

  final separateReviewDeps = revDepsToCommits.keys
      .where((dep) => individuallyReviewedPackages.contains(dep.name))
      .toList();
  revDepsToCommits
      .removeWhere((dep, _) => individuallyReviewedPackages.contains(dep.name));

  final depsToRevNames = revDepsToCommits.keys.map((e) => e.name).join(', ');

  print('Move moving forward revisions for: $depsToRevNames.');
  if (separateReviewDeps.isNotEmpty) {
    print('(additional, individually reviewed updates are also available for: '
        '${separateReviewDeps.map((dep) => dep.name).join(', ')})');
  }
  print('');
  print('Commit message:');
  print('');
  print('[deps] rev $depsToRevNames');
  print('');
  print('Revisions updated by `dart tools/rev_sdk_deps.dart`.');
  print('');

  for (final MapEntry(key: dep, value: commit) in revDepsToCommits.entries) {
    final git = GitHelper(dep.relativePath);

    final gitLog = await git.calculateUnsyncedCommits();
    final currentHash = await gclient.getHash(dep);

    final gitHubRepo = dep.gitHubRepoIdentifier;

    // Construct and print out the GitHub diff URL.
    print('${dep.name} (${dep.gitHubDiffUrl(currentHash, commit)}):');

    /// Qualify or wrap the GitHub issue references within [commitMessage].
    String replaceHashReferences(String commitMessage) => commitMessage
        .replaceAllMapped(
          _mergeCommitPullRequestReference,
          (m) => '($gitHubRepo#${m[1]})',
        )
        .replaceAllMapped(_issueHashReference, (m) => '`${m[0]}`');

    // Format and print out the message header of each new commit.
    final newCommitHeaders = [
      for (final commitHeader in gitLog.split('\n'))
        '  ${replaceHashReferences(commitHeader)}',
    ];
    print(newCommitHeaders.join('\n').trimRight());

    // Update the DEPS file.
    await gclient.setHash(dep, commit);

    print('');
  }

  if (separateReviewDeps.isNotEmpty) {
    final boldText = Ansi(true)
        .emphasized('Note: updates are also available for additional packages');
    print('$boldText; these require individual review.\nPlease ensure that the '
        'review for these changes is thorough. To roll them:');
    print('');
    for (var dep in separateReviewDeps) {
      print('${dep.name} from ${dep.url}:');
      print('  dart tools/manage_deps.dart bump third_party/pkg/${dep.name}');
      print('');
    }
  }
}

/// A regex that matches the final PR reference of a merge commit header.
///
/// Allows replacing the PR reference with a repository qualified reference,
/// so that GitHub auto links to the correct repository instead of
/// an irrelevant issue or PR on the SDK repository.
final RegExp _mergeCommitPullRequestReference = RegExp(r'\(#?(\d+)\)$');

/// A regex that matches any non-qualified issue or PR references
/// within a commit message, such as `#123`.
///
/// Allows replacing or wrapping the potential issue or PR references so that
/// GitHub doesn't autolink to an irrelevant issue or PR on the SDK repository.
final RegExp _issueHashReference = RegExp(r'\B#\d+');

// By convention, pinned deps are deps with an eol comment.
Set<String> calculatePinnedDeps() {
  final packageRevision = RegExp(r'"(\w+)_rev":');

  // "markdown_rev": "e3f4bd28c9...cfeccd83ee", # b/236358256
  var depsFile = File('DEPS');
  return depsFile
      .readAsLinesSync()
      .where((line) => packageRevision.hasMatch(line) && line.contains('", #'))
      .map((line) => packageRevision.firstMatch(line)!.group(1)!)
      .toSet();
}

class GitHelper {
  final String dir;

  GitHelper(this.dir);

  Future<String> fetch() {
    return exec(['git', 'fetch'], cwd: dir);
  }

  Future<String> findLatestUnsyncedCommit() async {
    // git log ..origin/<default-branch> --format=%H -1

    var result = await exec(
      [
        'git',
        'log',
        '..origin/$defaultBranchName',
        '--format=%H',
        '-1',
      ],
      cwd: dir,
    );
    return result.trim();
  }

  Future<String> calculateUnsyncedCommits() async {
    // git log ..origin/<default-branch> --format="%h  %ad  %aN  %s" -1
    var result = await exec(
      [
        'git',
        'log',
        '..origin/$defaultBranchName',
        '--format=%h  %ad  %aN  %s',
      ],
      cwd: dir,
    );
    return result.trim();
  }

  String get defaultBranchName {
    var branchNames = Directory(path.join(dir, '.git', 'refs', 'heads'))
        .listSync()
        .whereType<File>()
        .map((f) => path.basename(f.path))
        .toSet();

    for (var name in ['main', 'master']) {
      if (branchNames.contains(name)) {
        return name;
      }
    }

    return 'main';
  }
}

class GClientHelper {
  Future<List<PackageDependency>> getPackageDependencies() async {
    // gclient revinfo --output-json=<file> --ignore-dep-type=cipd

    final tempDir = Directory.systemTemp.createTempSync();
    final outFile = File(path.join(tempDir.path, 'deps.json'));

    await exec([
      'gclient',
      'revinfo',
      '--output-json=${outFile.path}',
      '--ignore-dep-type=cipd',
    ]);
    Map<String, dynamic> m = jsonDecode(outFile.readAsStringSync());
    tempDir.deleteSync(recursive: true);

    return m.entries.map((entry) {
      return PackageDependency(
        entry: entry.key,
        url: (entry.value as Map)['url'],
        rev: (entry.value as Map)['rev'],
      );
    }).where((PackageDependency deps) {
      return deps.entry.startsWith('sdk/third_party/pkg/');
    }).toList();
  }

  Future<String> getHash(PackageDependency dep) async {
    // DEPOT_TOOLS_UPDATE=0 gclient getdep --var=path_rev
    var depName = dep.name;
    var result = await exec(
      [
        'gclient',
        'getdep',
        '--var=${depName}_rev',
      ],
      environment: {
        'DEPOT_TOOLS_UPDATE': '0',
      },
    );
    return result.trim();
  }

  Future<String> setHash(PackageDependency dep, String hash) async {
    // gclient setdep --var=args_rev=9879dsf7g9d87d9f8g7
    var depName = dep.name;
    return await exec(
      [
        'gclient',
        'setdep',
        '--var=${depName}_rev=$hash',
      ],
      environment: {
        'DEPOT_TOOLS_UPDATE': '0',
      },
    );
  }
}

class PackageDependency {
  final String entry;
  final String url;
  final String? rev;

  PackageDependency({
    required this.entry,
    required this.url,
    required this.rev,
  });

  String get name => entry.substring(entry.lastIndexOf('/') + 1);

  String get relativePath => entry.substring('sdk/'.length);

  /// The identifier of the GitHub repository this dependency is from.
  ///
  /// For example: `dart-lang/test`.
  String get gitHubRepoIdentifier {
    var repo = url.substring(url.lastIndexOf('/') + 1);
    if (repo.endsWith('git')) {
      repo = repo.substring(0, repo.length - '.git'.length);
    }

    final String org;
    if (url.contains('/external/')) {
      // https://dart.googlesource.com/external/github.com/google/webdriver.dart.git
      final parts = url.split('/');
      org = parts[parts.length - 2];
    } else {
      org = 'dart-lang';
    }

    return '$org/$repo';
  }

  /// The URL of the GitHub comparison view between [fromCommit] and [toCommit].
  Uri gitHubDiffUrl(String fromCommit, String toCommit) {
    // https://github.com/dart-lang/<repo>/compare/<old>..<new>
    final from = fromCommit.substring(0, 7);
    final to = toCommit.substring(0, 7);

    return Uri.https('github.com', '$gitHubRepoIdentifier/compare/$from..$to');
  }

  @override
  String toString() => '${rev?.substring(0, 8)} $relativePath';
}

Future<String> exec(
  List<String> cmd, {
  String? cwd,
  Map<String, String>? environment,
}) async {
  var result = await Process.run(
    cmd.first,
    cmd.sublist(1),
    workingDirectory: cwd,
    environment: environment,
  );
  if (result.exitCode != 0) {
    var cwdLocation = cwd == null ? '' : ' ($cwd)';
    print('${cmd.join(' ')}$cwdLocation');

    if ((result.stdout as String).isNotEmpty) {
      stdout.write(result.stdout);
    }
    if ((result.stderr as String).isNotEmpty) {
      stderr.write(result.stderr);
    }
    exit(1);
  }
  return result.stdout;
}
