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

@Timeout(Duration(seconds: 120))

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

import 'package:test/test.dart';

void main() {
  Uri? tempDirUri;
  final projectName = 'test_project';

  setUp(() async {
    tempDirUri = (await Directory.current.createTemp('.temp_test_')).uri;
  });

  tearDown(() async {
    final dir = Directory(tempDirUri!.toFilePath());
    if (await dir.exists()) {
      await dir.delete(recursive: true);
    }
  });

  test('Run Flutter', () async {
    final projectDirUri = tempDirUri!.resolve('$projectName/');
    final libDirUri = projectDirUri.resolve('lib/');
    final bindingsGeneratedUri =
        libDirUri.resolve('${projectName}_bindings_generated.dart');
    final bindingsGeneratedCopyUri =
        libDirUri.resolve('${projectName}_bindings_generated_copy.dart');

    await Task.serial([
      RunProcess(
        executable: 'flutter',
        arguments: [
          'create',
          '--template=plugin_ffi',
          projectName,
        ],
        workingDirectory: tempDirUri,
      ),
      Copy(
        source: bindingsGeneratedUri,
        target: bindingsGeneratedCopyUri,
      ),
      RunProcess(
        executable: 'flutter',
        arguments: [
          'pub',
          'run',
          'ffigen',
          '--config',
          'ffigen.yaml',
        ],
        workingDirectory: projectDirUri,
      ),
    ]).run();

    final originalBindings = await readFileAsString(bindingsGeneratedCopyUri);
    final regeneratedBindings = await readFileAsString(bindingsGeneratedUri);

    expect(originalBindings, regeneratedBindings);
  });
}

Future<String> readFileAsString(Uri uri) async {
  final contents = await File(uri.toFilePath()).readAsString();
  return contents.replaceAll('\r', '');
}

abstract class Task {
  Future<void> run();

  factory Task.serial(Iterable<Task> tasks) => _SerialTask(tasks);
}

class _SerialTask implements Task {
  final Iterable<Task> tasks;

  _SerialTask(this.tasks);

  @override
  Future<void> run() async {
    for (final task in tasks) {
      await task.run();
    }
  }
}

class RunProcess implements Task {
  final List<String> arguments;
  final String executable;
  final Uri? workingDirectory;
  Map<String, String>? environment;
  final bool throwOnFailure;

  RunProcess({
    required this.arguments,
    required this.executable,
    this.workingDirectory,
    this.environment,
    this.throwOnFailure = true,
  });

  /// Excluding [workingDirectory].
  String get commandString => [
        if (workingDirectory != null) '(cd ${workingDirectory!.path};',
        ...?environment?.entries.map((entry) => '${entry.key}=${entry.value}'),
        executable,
        ...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
        if (workingDirectory != null) ')',
      ].join(' ');

  @override
  Future<void> run() async {
    final workingDirectoryString = workingDirectory?.toFilePath();

    print('Running `$commandString`.');
    final process = await Process.start(executable, arguments,
            runInShell: true,
            includeParentEnvironment: true,
            workingDirectory: workingDirectoryString,
            environment: environment)
        .then((process) {
      process.stdout.transform(utf8.decoder).forEach((s) => print('  $s'));
      process.stderr.transform(utf8.decoder).forEach((s) => print('  $s'));
      return process;
    });
    final exitCode = await process.exitCode;
    if (exitCode != 0) {
      final message =
          'Command `$commandString` failed with exit code $exitCode.';
      print(message);
      if (throwOnFailure) {
        throw Exception(message);
      }
    }
    print('Command `$commandString` done.');
  }
}

class Copy implements Task {
  final Uri source;
  final Uri target;

  Copy({
    required this.source,
    required this.target,
  });

  @override
  Future<void> run() async {
    final file = File.fromUri(source);
    if (!await file.exists()) {
      final message =
          "File not in expected location: '${source.toFilePath()}'.";
      print(message);
      throw Exception(message);
    }
    print('Copying ${source.toFilePath()} to ${target.toFilePath()}.');
    await file.copy(target.toFilePath());
  }
}
