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

import 'dart:io' as io;

import 'package:git_repo_tools/git_repo_tools.dart';
import 'package:litetest/litetest.dart';
import 'package:process_fakes/process_fakes.dart';

void main() {
  const String fakeShaHash = 'fake-sha-hash';


  test('returns non-deleted files which differ from merge-base with main', () async {
    final Fixture fixture = Fixture(
      processManager: FakeProcessManager(
        onStart: (List<String> command) {
          // Succeed calling "git merge-base --fork-point FETCH_HEAD HEAD".
          if (command.join(' ').startsWith('git merge-base --fork-point')) {
            return FakeProcess(stdout: fakeShaHash);
          }

          // Succeed calling "git fetch upstream main".
          if (command.join(' ') == 'git fetch upstream main') {
            return FakeProcess();
          }

          // Succeed calling "git diff --name-only --diff-filter=ACMRT fake-sha-hash".
          if (command.join(' ') == 'git diff --name-only --diff-filter=ACMRT $fakeShaHash') {
            return FakeProcess(stdout: 'file1\nfile2');
          }

          // Otherwise, fail.
          return FakeProcessManager.unhandledStart(command);
        },
      ),
    );

    try {
      final List<io.File> changedFiles = await fixture.gitRepo.changedFiles;
      expect(changedFiles, hasLength(2));
      expect(changedFiles[0].path, endsWith('file1'));
      expect(changedFiles[1].path, endsWith('file2'));
    } finally {
      fixture.gitRepo.root.deleteSync(recursive: true);
    }
  });

  test('returns non-deleted files which differ from default merge-base', () async {
    final Fixture fixture = Fixture(
      processManager: FakeProcessManager(
        onStart: (List<String> command) {
          if (command.join(' ').startsWith('git merge-base --fork-point')) {
            return FakeProcess(exitCode: 1);
          }

          if (command.join(' ').startsWith('git merge-base')) {
            return FakeProcess(stdout: fakeShaHash);
          }

          if (command.join(' ') == 'git fetch upstream main') {
            return FakeProcess();
          }

          if (command.join(' ') == 'git diff --name-only --diff-filter=ACMRT $fakeShaHash') {
            return FakeProcess(stdout: 'file1\nfile2');
          }

          // Otherwise, fail.
          return FakeProcessManager.unhandledStart(command);
        },
      ),
    );

    try {
      final List<io.File> changedFiles = await fixture.gitRepo.changedFiles;
      expect(changedFiles, hasLength(2));
      expect(changedFiles[0].path, endsWith('file1'));
      expect(changedFiles[1].path, endsWith('file2'));
    } finally {
      fixture.gitRepo.root.deleteSync(recursive: true);
    }
  });

  test('returns non-deleted files which differ from HEAD', () async {
    final Fixture fixture = Fixture(
      processManager: FakeProcessManager(
        onStart: (List<String> command) {
          if (command.join(' ') == 'git fetch upstream main') {
            return FakeProcess();
          }

          if (command.join(' ') == 'git diff-tree --no-commit-id --name-only --diff-filter=ACMRT -r HEAD') {
            return FakeProcess(stdout: 'file1\nfile2');
          }

          // Otherwise, fail.
          return FakeProcessManager.unhandledStart(command);
        },
      ),
    );

    try {
      final List<io.File> changedFiles = await fixture.gitRepo.changedFilesAtHead;
      expect(changedFiles, hasLength(2));
      expect(changedFiles[0].path, endsWith('file1'));
      expect(changedFiles[1].path, endsWith('file2'));
    } finally {
      fixture.gitRepo.root.deleteSync(recursive: true);
    }
  });

  test('returns non-deleted files which differ from HEAD when merge-base fails', () async {
    final Fixture fixture = Fixture(
      processManager: FakeProcessManager(
        onStart: (List<String> command) {
          if (command.join(' ') == 'git fetch upstream main') {
            return FakeProcess();
          }

          if (command.join(' ') == 'git diff-tree --no-commit-id --name-only --diff-filter=ACMRT -r HEAD') {
            return FakeProcess(stdout: 'file1\nfile2');
          }

          if (command.join(' ').startsWith('git merge-base --fork-point')) {
            return FakeProcess(exitCode: 1);
          }

          if (command.join(' ').startsWith('git merge-base')) {
            return FakeProcess(stdout: fakeShaHash);
          }

          // Otherwise, fail.
          return FakeProcessManager.unhandledStart(command);
        },
      ),
    );

    try {
      final List<io.File> changedFiles = await fixture.gitRepo.changedFilesAtHead;
      expect(changedFiles, hasLength(2));
      expect(changedFiles[0].path, endsWith('file1'));
      expect(changedFiles[1].path, endsWith('file2'));
    } finally {
      fixture.gitRepo.root.deleteSync(recursive: true);
    }
  });

  test('verbose output is captured', () async {
    final Fixture fixture = Fixture(
      processManager: FakeProcessManager(
        onStart: (List<String> command) {
          if (command.join(' ').startsWith('git merge-base --fork-point')) {
            return FakeProcess(exitCode: 1);
          }

          if (command.join(' ').startsWith('git merge-base')) {
            return FakeProcess(stdout: fakeShaHash);
          }

          if (command.join(' ') == 'git fetch upstream main') {
            return FakeProcess();
          }

          if (command.join(' ') == 'git diff --name-only --diff-filter=ACMRT $fakeShaHash') {
            return FakeProcess(stdout: 'file1\nfile2');
          }

          // Otherwise, fail.
          return FakeProcessManager.unhandledStart(command);
        },
      ),
      verbose: true,
    );

    try {
      await fixture.gitRepo.changedFiles;
      expect(fixture.logSink.toString(), contains('git merge-base --fork-point failed, using default merge-base'));
      expect(fixture.logSink.toString(), contains('git diff output:\nfile1\nfile2'));
    } finally {
      fixture.gitRepo.root.deleteSync(recursive: true);
    }
  });
}

final class Fixture {
  factory Fixture({
    FakeProcessManager? processManager,
    bool verbose = false,
  }) {
    final io.Directory root = io.Directory.systemTemp.createTempSync('git_repo_tools.test');
    final StringBuffer logSink = StringBuffer();
    processManager ??= FakeProcessManager();
    return Fixture._(
      gitRepo: GitRepo.fromRoot(root,
        logSink: logSink,
        processManager: processManager,
        verbose: verbose,
      ),
      logSink: logSink,
    );
  }

  const Fixture._({
    required this.gitRepo,
    required this.logSink,
  });

  final GitRepo gitRepo;
  final StringBuffer logSink;
}
