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

import 'dart:io' as io;

import 'package:path/path.dart' as path;
import 'package:test/test.dart';

class FileContentPair {
  FileContentPair({required this.name, required this.original, required this.formatted});

  final String name;
  final String original;
  final String formatted;
}

final FileContentPair dartContentPair = FileContentPair(
  name: 'format_test.dart',
  original: 'enum \n\nfoo {\n  entry1,\n  entry2,\n}',
  formatted: 'enum foo { entry1, entry2 }\n',
);

class TestFileFixture {
  TestFileFixture(this.filePairs, this.baseDir) {
    for (final FileContentPair filePair in filePairs) {
      final file = io.File(path.join(baseDir.path, filePair.name));
      file.writeAsStringSync(filePair.original);
      files.add(file);
    }
  }

  final List<io.File> files = <io.File>[];
  final io.Directory baseDir;
  final List<FileContentPair> filePairs;

  void gitAdd() {
    final args = <String>['add'];
    for (final io.File file in files) {
      args.add(file.path);
    }

    io.Process.runSync('git', args);
  }

  void gitRemove() {
    final args = <String>['rm', '-f'];
    for (final io.File file in files) {
      args.add(file.path);
    }
    io.Process.runSync('git', args);
  }

  Iterable<FileContentPair> getFileContents() {
    final results = <FileContentPair>[];
    for (var i = 0; i < files.length; i++) {
      final io.File file = files[i];
      final FileContentPair filePair = filePairs[i];
      final String content = file.readAsStringSync().replaceAll('\r\n', '\n');
      results.add(
        FileContentPair(name: filePair.name, original: content, formatted: filePair.formatted),
      );
    }
    return results;
  }
}

void main() {
  final io.File script = io.File(path.current).absolute;
  final io.Directory flutterRoot = script.parent.parent;
  final String formatterPath = path.join(
    flutterRoot.path,
    'dev',
    'tools',
    'format.${io.Platform.isWindows ? 'bat' : 'sh'}',
  );

  test(
    'Can fix Dart formatting errors',
    () {
      final fixture = TestFileFixture(<FileContentPair>[dartContentPair], flutterRoot);
      try {
        fixture.gitAdd();
        io.Process.runSync(formatterPath, <String>['--fix'], workingDirectory: flutterRoot.path);

        final Iterable<FileContentPair> files = fixture.getFileContents();
        for (final pair in files) {
          expect(pair.original, equals(pair.formatted));
        }
      } finally {
        fixture.gitRemove();
      }
    },
    // [intended] TODO(goderbauer): Re-enable after the formatting changes have landed.
    skip: true,
  );

  test(
    'Prints error if dart formatter fails',
    () {
      final fixture = TestFileFixture(<FileContentPair>[], flutterRoot);
      final dartFile = io.File('${flutterRoot.path}/format_test2.dart');
      dartFile.writeAsStringSync('P\n');
      fixture.files.add(dartFile);

      try {
        fixture.gitAdd();
        final io.ProcessResult result = io.Process.runSync(formatterPath, <String>[
          '--fix',
        ], workingDirectory: flutterRoot.path);
        expect(result.stdout, contains('format_test2.dart produced the following error'));
        expect(result.exitCode, isNot(0));
      } finally {
        fixture.gitRemove();
      }
    },
    // [intended] TODO(goderbauer): Re-enable after the formatting changes have landed.
    skip: true,
  );
}
