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

// This is a script to run a subset of CI checks on development machine before
// submitting PR. This prevents from accidentally forgetting to format or
// remove an unused import.

// This is rough around the edges. This script may give false positives such
// as some gitignore'd temporary files failing the comparison.

// On windows, please install 'diffutils' using your favorite package installer
// for this script to work correctly. Also ensure that clang-format is on your
// PATH.

import 'dart:async';
import 'dart:io';

import 'package:args/args.dart';

import 'command_runner.dart';

// Flags
const _clone = 'clone';

void main(List<String> arguments) async {
  final parser = ArgParser()
    ..addFlag(
      _clone,
      help: 'Run checks in a cloned copy of the project.',
      defaultsTo: true,
      negatable: true,
    );
  final argResults = parser.parse(arguments);
  final shouldClone = argResults[_clone] as bool;
  final gitRoot = getRepositoryRoot();

  // change to project root
  Directory.current = gitRoot.toFilePath();

  var tempDir = Directory.current;
  if (shouldClone) {
    tempDir = Directory.current.createTempSync('jnigen_checks_clone_');
    final gitClone = Runner("Clone jni", Directory.current.uri)
      ..chainCommand('git', ['clone', '.', tempDir.path]);
    await gitClone.run();
  }

  final jniPath = tempDir.uri.resolve("jni/");
  final jnigenPath = tempDir.uri.resolve("jnigen/");
  final pubGet = Runner("Pub get", tempDir.uri)
    ..chainCommand("flutter", ["pub", "get", "--offline"],
        workingDirectory: jniPath)
    ..chainCommand("dart", ["pub", "get", "--offline"],
        workingDirectory: jnigenPath);
  await pubGet.run();

  final jniAnalyze = Runner("Analyze JNI", jniPath);
  jniAnalyze
    ..chainCommand("dart", ["analyze", "--fatal-infos"])
    ..chainCommand(
        "dart", ["format", "--output=none", "--set-exit-if-changed", "."])
    ..chainCommand(
        "clang-format",
        [
          "--dry-run",
          "-Werror",
          "dartjni.c",
          "dartjni.h",
          "third_party/global_jni_env.c",
          "third_party/global_jni_env.h",
        ],
        workingDirectory: jniPath.resolve("src/"));
  final jniTest = Runner("Test JNI", jniPath)
    ..chainCommand("dart", ["run", "jni:setup"])
    ..chainCommand("dart", ["test", "-j", "1"]);
  unawaited(jniAnalyze.run().then((f) => jniTest.run()));

  List<String> getJavaFiles(String relativePath) =>
      Directory.fromUri(jnigenPath.resolve(relativePath))
          .listSync(recursive: true)
          .where((file) => file.path.endsWith(".java"))
          .map((file) => file.path)
          .toList();

  final javaFiles = getJavaFiles("java/") +
      getJavaFiles("test/simple_package_test") +
      getJavaFiles("example/in_app_java") +
      getJavaFiles("example/notification_plugin");

  final checkJavaFormat = Runner("Check java format", jnigenPath)
    ..chainCommand(
        "google-java-format", ["-n", "--set-exit-if-changed", ...javaFiles]);

  unawaited(checkJavaFormat.run());

  final ffigenBindingsPath = getRepositoryRoot()
      .resolve("jni/lib/src/third_party/jni_bindings_generated.dart");
  final ffigenBindings = File.fromUri(ffigenBindingsPath);
  final oldBindingsText = ffigenBindings.readAsStringSync();
  final ffigenCompare = Runner("Generate & Compare FFIGEN bindings", jniPath)
    ..chainCommand("dart", ["run", "ffigen", "--config", "ffigen.yaml"])
    ..chainCallback("compare bindings", () async {
      final newBindingsText = await ffigenBindings.readAsString();
      if (newBindingsText != oldBindingsText) {
        await ffigenBindings.writeAsString(oldBindingsText);
        throw "new JNI.h bindings differ from old bindings";
      }
    });
  unawaited(ffigenCompare.run());

  final jnigenAnalyze = Runner("Analyze jnigen", jnigenPath)
    ..chainCommand("dart", ["analyze", "--fatal-infos"])
    ..chainCommand(
        "dart", ["format", "--output=none", "--set-exit-if-changed", "."])
    ..chainCommand("dart", ["run", "jnigen:setup"]);

  // Tests may need more time when running on systems with less cores.
  // So '--timeout 2x' is specified.
  final jnigenTest = Runner("Test jnigen", gitRoot.resolve("jnigen/"))
    ..chainCommand("dart", ["test", "--timeout", "2x"]);

  // Note: Running in_app_java and notification_plugin checks on source dir
  // itself, because running flutter build in cloned dir will take time.
  final compareInAppJavaBindings = Runner(
      "Generate & compare InAppJava bindings",
      gitRoot.resolve("jnigen/example/in_app_java"))
    ..chainCommand("dart", [
      "run",
      "jnigen",
      "--config",
      "jnigen.yaml",
      "-Doutput.c.path=src_temp/",
      "-Doutput.dart.path=_temp.dart",
    ])
    ..chainCommand("diff", ["lib/android_utils.dart", "_temp.dart"])
    ..chainCommand("diff", ["-qr", "src/android_utils/", "src_temp/"])
    ..chainCleanupCommand("rm", ["-r", "_temp.dart", "src_temp"]);

  final comparePdfboxBindings = Runner("Generate & compare PdfBox Bindings",
      gitRoot.resolve("jnigen/example/pdfbox_plugin"))
    ..chainCommand("dart", [
      "run",
      "jnigen",
      "--config",
      "jnigen.yaml",
      "-Doutput.c.path=src_temp/",
      "-Doutput.dart.path=lib_temp/",
    ])
    ..chainCommand("diff", ["-qr", "lib/src/third_party/", "lib_temp/"])
    ..chainCommand("diff", ["-qr", "src/", "src_temp/"])
    ..chainCleanupCommand("rm", ["-r", "lib_temp", "src_temp"]);

  final compareNotificationPluginBindings = Runner(
      "Generate & compare NotificationPlugin Bindings",
      gitRoot.resolve("jnigen/example/notification_plugin"))
    ..chainCommand("dart", [
      "run",
      "jnigen",
      "--config",
      "jnigen.yaml",
      "-Doutput.c.path=src_temp/",
      "-Doutput.dart.path=_temp.dart",
    ])
    ..chainCommand("diff", ["lib/notifications.dart", "_temp.dart"])
    ..chainCommand("diff", ["-qr", "src/", "src_temp/"])
    ..chainCleanupCommand("rm", ["-r", "_temp.dart", "src_temp"]);

  unawaited(jnigenAnalyze.run().then((_) {
    final test = jnigenTest.run();
    final inAppJava = compareInAppJavaBindings.run();
    final pdfBox = comparePdfboxBindings.run();
    final notificationPlugin = compareNotificationPluginBindings.run();
    return Future.wait([test, inAppJava, pdfBox, notificationPlugin]);
  }).then((_) {
    if (shouldClone) {
      tempDir.deleteSync(recursive: true);
    }
  }));
}
