// 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:convert';
import 'dart:io' show File, FileSystemException;
import 'dart:vmservice_io' show getResidentCompilerInfoFileConsideringArgsImpl;

import 'package:args/args.dart';
import 'package:frontend_server/resident_frontend_server_utils.dart'
    show sendAndReceiveResponse;
import 'package:path/path.dart' as p;

import 'commands/compilation_server.dart' show CompilationServerCommand;
import 'resident_frontend_constants.dart';

/// The Resident Frontend Compiler's shutdown command.
final residentServerShutdownCommand = jsonEncode(
  <String, Object>{
    commandString: shutdownString,
  },
);

File? getResidentCompilerInfoFileConsideringArgs(final ArgResults args) =>
    getResidentCompilerInfoFileConsideringArgsImpl(
        args[CompilationServerCommand.residentCompilerInfoFileFlag] ??
            args[CompilationServerCommand.legacyResidentServerInfoFileFlag]);

final String packageConfigName = p.join('.dart_tool', 'package_config.json');

/// Removes the [serverInfoFile].
void cleanupResidentServerInfo(File serverInfoFile) {
  if (serverInfoFile.existsSync()) {
    try {
      serverInfoFile.deleteSync();
    } catch (_) {}
  }
}

/// First, attempts to shut down the Resident Frontend Compiler associated with
/// [infoFile]. If successful, [infoFile] is deleted. If any error occurs
/// preventing shutdown, the error is ignored and [infoFile] is deleted, making
/// the compiler be forgetten. The forgotten compiler will shut itself down a
/// certain period of inactivity (see the inactivityTimeout parameter of
/// residentListenAndCompile in
/// pkg/frontend_server/lib/src/resident_frontend_server.dart).
Future<void> shutDownOrForgetResidentFrontendCompiler(File infoFile) async {
  try {
    // As explained in the doc comment above, this function ignores errors. So,
    // we ignore the return value of [sendAndReceiveResponse].
    await sendAndReceiveResponse(
      residentServerShutdownCommand,
      infoFile,
    );
  } on FileSystemException catch (_) {
    // As explained in the doc comment above, this function ignores errors. We
    // only catch [FileSystemException]s because [sendAndReceiveResponse] cannot
    // throw any other type of error.
  }
  cleanupResidentServerInfo(infoFile);
}

Future<bool> isFileKernelFile(final File file) async {
  final bytes = await file.openRead(0, 4).expand((i) => i).toList();
  if (bytes.length < 4) {
    return false;
  }
  // Check for the magic number at the start of kernel files.
  return bytes[0] == 0x90 &&
      bytes[1] == 0xab &&
      bytes[2] == 0xcd &&
      bytes[3] == 0xef;
}

Future<bool> isFileAppJitSnapshot(final File file) async {
  final bytes = await file.openRead(0, 8).expand((i) => i).toList();
  if (bytes.length < 8) {
    return false;
  }
  // Check for the magic number at the start of AppJIT snapshots.
  return bytes[0] == 0xdc &&
      bytes[1] == 0xdc &&
      bytes[2] == 0xf6 &&
      bytes[3] == 0xf6 &&
      bytes[4] == 0 &&
      bytes[5] == 0 &&
      bytes[6] == 0 &&
      bytes[7] == 0;
}

Future<bool> isFileAotSnapshot(final File file) async {
  // Check for any of the magic numbers that can be found at the start of an
  // AOT snapshot.

  final bytes = await file.openRead(0, 4).expand((i) => i).toList();
  // Check for the COFF magic numbers.
  if (bytes.length < 2) {
    return false;
  }
  if (bytes[0] == 0x01 && bytes[1] == 0xc0 || // arm32
      bytes[0] == 0xaa && bytes[1] == 0x64 || // arm64
      bytes[0] == 0x50 && bytes[1] == 0x32 || // riscv32
      bytes[0] == 0x50 && bytes[1] == 0x64 /* riscv64 */) {
    return true;
  }

  if (bytes.length < 4) {
    return false;
  }
  // Check for the ELF magic number.
  if (bytes[0] == 0x7f &&
      bytes[1] == 0x45 &&
      bytes[2] == 0x4c &&
      bytes[3] == 0x46) {
    return true;
  }
  // Check for the Mach-O magic numbers.
  if (bytes[0] == 0xfe &&
      bytes[1] == 0xed &&
      bytes[2] == 0xfa &&
      bytes[3] == 0xce) {
    // macho32
    return true;
  }
  if (bytes[0] == 0xfe &&
      bytes[1] == 0xed &&
      bytes[2] == 0xfa &&
      bytes[3] == 0xcf) {
    // macho64
    return true;
  }
  if (bytes[0] == 0xcf &&
      bytes[1] == 0xfa &&
      bytes[2] == 0xed &&
      bytes[3] == 0xfe) {
    // macho64_arm64
    return true;
  }

  return false;
}

/// Used to create compile requests for the run CLI command.
///
/// Returns a JSON string that the resident compiler will be able to interpret.
String createCompileJitJson({
  required String executable,
  required String outputDill,
  required ArgResults args,
  String? packages,
  bool verbose = false,
}) {
  return jsonEncode(
    <String, Object?>{
      commandString: compileString,
      sourceString: executable,
      outputString: outputDill,
      if (args.wasParsed(defineOption))
        defineOption: args.multiOption(defineOption),
      if (args.options.contains(enableAssertsOption) &&
          args.wasParsed(enableAssertsOption))
        enableAssertsOption: true,
      if (args.wasParsed(enableExperimentOption))
        enableExperimentOption: args
            .multiOption(enableExperimentOption)
            .map((e) => '--enable-experiment=$e')
            .toList(),
      if (packages != null) packageString: packages,
      if (args.wasParsed(verbosityOption))
        verbosityOption: args.flag(verbosityOption),
    },
  );
}
