// Copyright (c) 2019, 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:convert';
import 'dart:io';
import 'dart:ffi';

import 'package:expect/config.dart';
import 'package:expect/expect.dart';
import 'package:native_stack_traces/src/elf.dart' show Elf;
import 'package:native_stack_traces/src/dwarf_container.dart'
    show DwarfContainer;
import 'package:native_stack_traces/src/macho.dart' show MachO;
import 'package:path/path.dart' as path;

final isAOTRuntime = isVmAotConfiguration;
final buildDir = path.dirname(Platform.executable);
final sdkDir = path.dirname(path.dirname(buildDir));
late final platformDill = () {
  final possiblePaths = [
    // No cross compilation.
    path.join(buildDir, 'vm_platform.dill'),
    // ${MODE}SIMARM_X64 for X64->SIMARM cross compilation.
    path.join('${buildDir}_X64', 'vm_platform.dill'),
  ];
  for (final path in possiblePaths) {
    if (File(path).existsSync()) {
      return path;
    }
  }
  throw 'Could not find vm_platform.dill for build directory $buildDir';
}();
final genKernel = path.join(
  sdkDir,
  'pkg',
  'vm',
  'tool',
  'gen_kernel' + (Platform.isWindows ? '.bat' : ''),
);
final genKernelDart = path.join('pkg', 'vm', 'bin', 'gen_kernel.dart');
final _genSnapshotBase = 'gen_snapshot' + (Platform.isWindows ? '.exe' : '');
// Lazily initialize `genSnapshot` so that tests that don't use it on platforms
// that don't have a `gen_snapshot` don't fail.
late final genSnapshot = () {
  final possiblePaths = [
    // No cross compilation.
    path.join(buildDir, _genSnapshotBase),
    // ${MODE}SIMARM_X64 for X64->SIMARM cross compilation.
    path.join('${buildDir}_X64', _genSnapshotBase),
    // ${MODE}XARM64/clang_x64 for X64->ARM64 cross compilation.
    path.join(buildDir, 'clang_x64', _genSnapshotBase),
  ];
  for (final path in possiblePaths) {
    if (File(path).existsSync()) {
      return path;
    }
  }
  throw 'Could not find gen_snapshot for build directory $buildDir';
}();
final dart = path.join(buildDir, 'dartvm' + (Platform.isWindows ? '.exe' : ''));
final dartPrecompiledRuntime = path.join(
  buildDir,
  'dartaotruntime' + (Platform.isWindows ? '.exe' : ''),
);
final checkedInDartVM = path.join(
  'tools',
  'sdks',
  'dart-sdk',
  'bin',
  'dart' + (Platform.isWindows ? '.exe' : ''),
);
String? llvmTool(String name, {bool verbose = false}) {
  final clangBuildTools = clangBuildToolsDir;
  if (clangBuildTools != null) {
    final toolPath = path.join(clangBuildTools, name);
    if (File(toolPath).existsSync()) {
      return toolPath;
    }
    if (verbose) {
      print('Could not find $name binary at $toolPath');
    }
    return null;
  }
  if (verbose) {
    print('Could not find $name binary');
  }
  return null;
}

final isSimulator = path.basename(buildDir).contains('SIM');

String? get clangBuildToolsDir {
  String archDir;
  switch (Abi.current()) {
    case Abi.linuxX64:
      archDir = 'linux-x64';
      break;
    case Abi.linuxArm64:
      archDir = 'linux-arm64';
      break;
    case Abi.macosX64:
      archDir = 'mac-x64';
      break;
    case Abi.macosArm64:
      archDir = 'mac-arm64';
      break;
    case Abi.windowsX64:
    case Abi.windowsArm64: // We don't have a proper host win-arm64 toolchain.
      archDir = 'win-x64';
      break;
    default:
      return null;
  }
  var clangDir = path.join(sdkDir, 'buildtools', archDir, 'clang', 'bin');
  print(clangDir);
  return Directory(clangDir).existsSync() ? clangDir : null;
}

Future<void> assembleSnapshot(
  String assemblyPath,
  String snapshotPath, {
  bool debug = false,
}) async {
  if (!Platform.isLinux && !Platform.isMacOS && !Platform.isWindows) {
    throw "Unsupported platform ${Platform.operatingSystem} for assembling";
  }

  final ccFlags = <String>[];
  final ldFlags = <String>[];
  String cc = 'gcc';
  String shared = '-shared';

  final clangBuildTools = clangBuildToolsDir;
  if (clangBuildTools != null) {
    cc = path.join(clangBuildTools, Platform.isWindows ? 'clang.exe' : 'clang');
  } else {
    throw 'Cannot assemble for ${path.basename(buildDir)} '
        'without //buildtools on ${Platform.operatingSystem}';
  }

  if (Platform.isMacOS) {
    shared = '-dynamiclib';
    // Tell Mac linker to give up generating eh_frame from dwarf.
    ldFlags.add('-Wl,-no_compact_unwind');
    if (buildDir.endsWith('ARM64')) {
      ccFlags.add('--target=arm64-apple-darwin');
    } else {
      ccFlags.add('--target=x86_64-apple-darwin');
    }
  } else if (Platform.isLinux) {
    if (buildDir.endsWith('ARM')) {
      ccFlags.add('--target=armv7-linux-gnueabihf');
    } else if (buildDir.endsWith('ARM64')) {
      ccFlags.add('--target=aarch64-linux-gnu');
    } else if (buildDir.endsWith('X64')) {
      ccFlags.add('--target=x86_64-linux-gnu');
    } else if (buildDir.endsWith('RISCV64')) {
      ccFlags.add('--target=riscv64-linux-gnu');
    }
  }

  if (debug) {
    ccFlags.add('-g');
  }

  await run(cc, <String>[
    ...ccFlags,
    ...ldFlags,
    '-nostdlib',
    shared,
    '-o',
    snapshotPath,
    assemblyPath,
  ]);
}

Future<void> stripSnapshot(
  String snapshotPath,
  String strippedPath, {
  bool forceElf = false,
}) async {
  if (!Platform.isLinux && !Platform.isMacOS && !Platform.isWindows) {
    throw "Unsupported platform ${Platform.operatingSystem} for stripping";
  }

  var strip = 'strip';

  final clangBuildTools = clangBuildToolsDir;
  if (clangBuildTools != null) {
    strip = path.join(
      clangBuildTools,
      Platform.isWindows ? 'llvm-strip.exe' : 'llvm-strip',
    );
  } else {
    throw 'Cannot strip ELF files for ${path.basename(buildDir)} '
        'without //buildtools on ${Platform.operatingSystem}';
  }

  await run(strip, <String>['-o', strippedPath, snapshotPath]);
}

Future<ProcessResult> runHelper(
  String executable,
  List<String> args, {
  bool printStdout = true,
  bool printStderr = true,
}) async {
  print('Running $executable ${args.join(' ')}');

  final result = await Process.run(executable, args);
  print('Subcommand terminated with exit code ${result.exitCode}.');
  if (printStdout && result.stdout.isNotEmpty) {
    print('Subcommand stdout:');
    print(result.stdout);
  }
  if (printStderr && result.stderr.isNotEmpty) {
    print('Subcommand stderr:');
    print(result.stderr);
  }

  return result;
}

Future<bool> testExecutable(String executable) async {
  try {
    final result = await runHelper(executable, <String>['--version']);
    return result.exitCode == 0;
  } on ProcessException catch (e) {
    print('Got process exception: $e');
    return false;
  }
}

Future<void> run(String executable, List<String> args) async {
  final result = await runHelper(executable, args);

  if (result.exitCode != 0) {
    throw 'Command failed with unexpected exit code (was ${result.exitCode})';
  }
}

Future<void> runSilent(String executable, List<String> args) async {
  final result = await runHelper(
    executable,
    args,
    printStdout: false,
    printStderr: false,
  );

  if (result.exitCode != 0) {
    throw 'Command failed with unexpected exit code (was ${result.exitCode})';
  }
}

Future<List<String>> runOutput(
  String executable,
  List<String> args, {
  bool ignoreStdErr = false,
}) async {
  final result = await runHelper(executable, args);

  if (result.exitCode != 0) {
    throw 'Command failed with unexpected exit code (was ${result.exitCode})';
  }
  Expect.isTrue(result.stdout.isNotEmpty);
  if (!ignoreStdErr) {
    Expect.isTrue(result.stderr.isEmpty);
  }

  return LineSplitter.split(result.stdout).toList(growable: false);
}

Future<List<String>> runError(String executable, List<String> args) async {
  final result = await runHelper(executable, args);

  if (result.exitCode == 0) {
    throw 'Command did not fail with non-zero exit code';
  }
  Expect.isTrue(result.stdout.isEmpty);
  Expect.isTrue(result.stderr.isNotEmpty);

  return LineSplitter.split(result.stderr).toList(growable: false);
}

const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';

Future<void> withTempDir(String name, Future<void> fun(String dir)) async {
  final tempDir = Directory.systemTemp.createTempSync(name);
  try {
    await fun(tempDir.path);
  } finally {
    if (!Platform.environment.containsKey(keepTempKey) ||
        Platform.environment[keepTempKey]!.isEmpty) {
      tempDir.deleteSync(recursive: true);
    }
  }
}

enum SnapshotType {
  elf,
  machoDylib,
  assembly;

  String get kindString {
    switch (this) {
      case elf:
        return 'app-aot-elf';
      case machoDylib:
        return 'app-aot-macho-dylib';
      case assembly:
        return 'app-aot-assembly';
    }
  }

  String get fileArgumentName {
    switch (this) {
      case elf:
        return 'elf';
      case machoDylib:
        return 'macho';
      case assembly:
        return 'assembly';
    }
  }

  DwarfContainer? fromFile(String filename) {
    switch (this) {
      case elf:
        return Elf.fromFile(filename);
      case machoDylib:
        return MachO.fromFile(filename);
      case assembly:
        return Elf.fromFile(filename) ?? MachO.fromFile(filename);
    }
  }

  @override
  String toString() => name;
}

const _commonGenSnapshotArgs = <String>[
  // Make sure that the runs are deterministic so we can depend on the same
  // snapshot being generated each time.
  '--deterministic',
];

Future<void> createSnapshot(
  String scriptDill,
  SnapshotType snapshotType,
  String finalPath, [
  List<String> extraArgs = const [],
]) async {
  String output = finalPath;
  if (snapshotType == SnapshotType.assembly) {
    output = path.withoutExtension(finalPath) + '.S';
  }
  await run(genSnapshot, <String>[
    ..._commonGenSnapshotArgs,
    ...extraArgs,
    '--snapshot-kind=${snapshotType.kindString}',
    '--${snapshotType.fileArgumentName}=$output',
    scriptDill,
  ]);
  if (snapshotType == SnapshotType.assembly) {
    await assembleSnapshot(output, finalPath);
  }
}
