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

import 'dart:io';

import 'package:jnigen/jnigen.dart';
import 'package:path/path.dart' hide equals;
import 'package:test/test.dart';
import 'package:logging/logging.dart' show Level;

import 'package:jnigen/src/logging/logging.dart' show printError;

final _currentDirectory = Directory(".");

Directory getTempDir(String prefix) {
  return _currentDirectory.createTempSync(prefix);
}

Future<bool> isEmptyOrNotExistDir(String path) async {
  final dir = Directory(path);
  return (!await dir.exists()) || (await dir.list().length == 0);
}

/// Runs command, and prints output only if the exit status is non-zero.
Future<int> runCommand(String exec, List<String> args,
    {String? workingDirectory, bool runInShell = false}) async {
  final proc = await Process.run(exec, args,
      workingDirectory: workingDirectory, runInShell: runInShell);
  if (proc.exitCode != 0) {
    printError('command exited with exit status ${proc.exitCode}:\n'
        '$exec ${args.join(" ")}\n');
    printError(proc.stdout);
    printError(proc.stderr);
  }
  return proc.exitCode;
}

/// List all JAR files in [testRoot]/jar
Future<List<String>> getJarPaths(String testRoot) async {
  final jarPath = join(testRoot, 'jar');
  if (!await Directory(jarPath).exists()) {
    return [];
  }
  return Directory(jarPath)
      .list()
      .map((entry) => entry.path)
      .where((path) => path.endsWith('.jar'))
      .toList();
}

/// Read file normalizing CRLF to LF.
String readFile(File file) => file.readAsStringSync().replaceAll('\r\n', '\n');

/// Compares 2 hierarchies using `git diff --no-index`.
void comparePaths(String path1, String path2) {
  final proc = Process.runSync("git", [
    "diff",
    "--no-index",
    if (stderr.supportsAnsiEscapes) "--color=always",
    path1,
    path2,
  ]);
  if (proc.exitCode != 0) {
    stderr.writeln('\n${proc.stdout}');
    throw Exception("Files differ: ($path1, $path2)");
  }
}

Future<void> _generateTempBindings(Config config, Directory tempDir) async {
  final tempSrc = tempDir.uri.resolve("src/");
  final singleFile =
      config.outputConfig.dartConfig.structure == OutputStructure.singleFile;
  final tempLib = singleFile
      ? tempDir.uri.resolve("generated.dart")
      : tempDir.uri.resolve("lib/");
  if (config.outputConfig.bindingsType == BindingsType.cBased) {
    config.outputConfig.cConfig!.path = tempSrc;
  }
  config.outputConfig.dartConfig.path = tempLib;
  config.logLevel = Level.WARNING;
  await generateJniBindings(config);
}

/// Generates and compares bindings with reference bindings.
///
/// [dartReferenceBindings] can be directory or file depending on output
/// configuration.
///
/// If the config generates C code, [cReferenceBindings] must be a non-null
/// directory path.
Future<void> generateAndCompareBindings(Config config,
    String dartReferenceBindings, String? cReferenceBindings) async {
  final currentDir = Directory.current;
  final tempDir = currentDir.createTempSync("jnigen_test_temp");
  final tempSrc = tempDir.uri.resolve("src/");
  final singleFile =
      config.outputConfig.dartConfig.structure == OutputStructure.singleFile;
  final tempLib = singleFile
      ? tempDir.uri.resolve("generated.dart")
      : tempDir.uri.resolve("lib/");
  try {
    await _generateTempBindings(config, tempDir);
    comparePaths(dartReferenceBindings, tempLib.toFilePath());
    if (config.outputConfig.bindingsType == BindingsType.cBased) {
      comparePaths(cReferenceBindings!, tempSrc.toFilePath());
    }
  } finally {
    tempDir.deleteSync(recursive: true);
  }
}

Future<void> generateAndAnalyzeBindings(Config config) async {
  final tempDir = Directory.current.createTempSync("jnigen_test_temp");
  try {
    await _generateTempBindings(config, tempDir);
    final analyzeResult = Process.runSync("dart", ["analyze", tempDir.path]);
    expect(analyzeResult.exitCode, equals(0),
        reason: "Analyzer exited with non-zero status");
  } finally {
    tempDir.deleteSync(recursive: true);
  }
}
