// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This script looks at the current commit and branch of the git repository in
// which it was run, and finds the contemporary commit in the master branch of
// another git repository, whose path is provided on the command line. The
// contemporary commit is the one that was public at the time of the last commit
// on the master branch before the current commit's branch was created.

import 'dart:io';

const bool debugLogging = false;

void log(String message) {
  if (debugLogging)
    print(message);
}

class Commit {
  Commit(this.hash, this.timestamp);

  final String hash;
  final DateTime timestamp;

  static String formatArgument = '--format=%H %cI';

  static Commit parse(String line) {
    final int space = line.indexOf(' ');
    return Commit(line.substring(0, space), DateTime.parse(line.substring(space+1, line.length).trimRight()));
  }

  static List<Commit> parseList(String lines) {
    return lines.split('\n').where((String line) => line.isNotEmpty).map(parse).toList().reversed.toList();
  }
}

String findCommit({
  required String primaryRepoDirectory,
  required String primaryBranch,
  required String primaryTrunk,
  required String secondaryRepoDirectory,
  required String secondaryBranch,
}) {
  final Commit anchor;
  if (primaryBranch == primaryTrunk) {
    log('on $primaryTrunk, using last commit as anchor');
    anchor = Commit.parse(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, '--max-count=1', primaryBranch]));
  } else {
    final List<Commit> branchCommits = Commit.parseList(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, primaryBranch]));
    final List<Commit> trunkCommits = Commit.parseList(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, primaryTrunk]));
    if (branchCommits.isEmpty || trunkCommits.isEmpty || branchCommits.first.hash != trunkCommits.first.hash)
      throw StateError('Branch $primaryBranch does not seem to have a common history with trunk $primaryTrunk.');
    if (branchCommits.last.hash == trunkCommits.last.hash) {
      log('$primaryBranch is even with $primaryTrunk, using last commit as anchor');
      anchor = trunkCommits.last;
    } else {
      int index = 0;
      while (branchCommits.length > index && trunkCommits.length > index && branchCommits[index].hash == trunkCommits[index].hash)
        index += 1;
      log('$primaryBranch branched from $primaryTrunk ${branchCommits.length - index} commits ago, trunk has advanced by ${trunkCommits.length - index} commits since then.');
      anchor = trunkCommits[index - 1];
    }
  }
  return git(secondaryRepoDirectory, <String>[
    'log',
    '--format=%H',
    '--until=${anchor.timestamp.toIso8601String()}',
    '--max-count=1',
    secondaryBranch,
  ]);
}

String git(String workingDirectory, List<String> arguments) {
  final ProcessResult result = Process.runSync('git', arguments, workingDirectory: workingDirectory);
  if (result.exitCode != 0 || '${result.stderr}'.isNotEmpty)
    throw ProcessException('git', arguments, '${result.stdout}${result.stderr}', result.exitCode);
  return '${result.stdout}';
}

void main(List<String> arguments) {
  if (arguments.isEmpty || arguments.length > 2 || arguments.contains('--help') || arguments.contains('-h')) {
    print(
      'Usage: dart find_commit.dart [<path-to-primary-repo>] <path-to-secondary-repo>\n'
      'This script will find the commit in the secondary repo that was contemporary\n'
      'when the commit in the primary repo was created. If that commit is on a\n'
      "branch, then the date of the branch's creation is used instead.\n"
      'If <path-to-primary-repo> is omitted, the current directory is used for the\n'
      'primary repo.'
    );
  } else {
    final String primaryRepo = arguments.length == 1 ? '.' : arguments.first;
    final String secondaryRepo = arguments.last;
    print(findCommit(
      primaryRepoDirectory: primaryRepo,
      primaryBranch: git(primaryRepo, <String>['rev-parse', '--abbrev-ref', 'HEAD']).trim(),
      primaryTrunk: 'master',
      secondaryRepoDirectory: secondaryRepo,
      secondaryBranch: 'master',
    ).trim());
  }
}
