// 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 'package:expect/config.dart';
import 'package:expect/expect.dart';
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_strong.dill'),
    // ${MODE}SIMARM_X64 for X64->SIMARM cross compilation.
    path.join('${buildDir}_X64', 'vm_platform_strong.dill'),
  ];
  for (final path in possiblePaths) {
    if (File(path).existsSync()) {
      return path;
    }
  }
  throw 'Could not find vm_platform_strong.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, 'dart' + (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' : ''),
);
// Lazily initialize 'lipo' so that tests that don't use it on platforms
// that don't have it don't fail.
late final lipo = () {
  final path = "/usr/bin/lipo";
  if (File(path).existsSync()) {
    return path;
  }
  throw 'Could not find lipo binary at $path';
}();

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

String? get clangBuildToolsDir {
  String archDir;
  if (Platform.isLinux) {
    archDir = 'linux-x64';
  } else if (Platform.isMacOS) {
    archDir = 'mac-x64';
  } else {
    return null;
  }
  var clangDir = path.join(sdkDir, 'buildtools', archDir, 'clang', 'bin');
  return Directory(clangDir).existsSync() ? clangDir : null;
}

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

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

  if (buildDir.endsWith('SIMRISCV64')) {
    cc = 'riscv64-linux-gnu-gcc';
  } else if (isSimulator) {
    // For other simulators, depend on buildtools existing.
    final clangBuildTools = clangBuildToolsDir;
    if (clangBuildTools != null) {
      cc = path.join(clangBuildTools, 'clang');
    } else {
      throw 'Cannot assemble for ${path.basename(buildDir)} '
          'without //buildtools on ${Platform.operatingSystem}';
    }
  } else if (Platform.isMacOS) {
    cc = 'clang';
  }

  if (buildDir.endsWith('SIMARM')) {
    ccFlags.add('--target=armv7-linux-gnueabihf');
  } else if (buildDir.endsWith('SIMARM64')) {
    ccFlags.add('--target=aarch64-linux-gnu');
  } else if (buildDir.endsWith('SIMRISCV64')) {
    ccFlags.add('--target=riscv64-linux-gnu');
  } else 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('X64') || buildDir.endsWith('SIMARM64')) {
    ccFlags.add('-m64');
  }
  if (debug) {
    ccFlags.add('-g');
  }

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

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

  var strip = 'strip';

  if (isSimulator || (Platform.isMacOS && forceElf)) {
    final clangBuildTools = clangBuildToolsDir;
    if (clangBuildTools != null) {
      strip = path.join(clangBuildTools, '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) async {
  print('Running $executable ${args.join(' ')}');

  final result = await Process.run(executable, args);
  print('Subcommand terminated with exit code ${result.exitCode}.');
  if (result.stdout.isNotEmpty) {
    print('Subcommand stdout:');
    print(result.stdout);
  }
  if (result.exitCode != 0) {
    if (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<List<String>> runOutput(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})';
  }
  Expect.isTrue(result.stdout.isNotEmpty);
  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);
    }
  }
}
