// 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:args/args.dart';
import 'package:frontend_server/resident_frontend_server_utils.dart'
    show
        computeCachedDillAndCompilerOptionsPaths,
        ResidentCompilerInfo,
        sendAndReceiveResponse;
import 'package:kernel/binary/tag.dart' show isValidSdkHash;
import 'package:path/path.dart' as p;
import 'package:pub/pub.dart';

import 'core.dart';
import 'resident_frontend_constants.dart';
import 'resident_frontend_utils.dart';
import 'sdk.dart';
import 'unified_analytics.dart';

typedef CompileRequestGeneratorCallback =
    String Function({
      required String executable,
      required String outputDill,
      required ArgResults args,
      String? packages,
      String? nativeAssetsYaml,
    });

/// Uses the resident frontend compiler to compute a kernel file for
/// [executable]. Throws a [FrontendCompilerException] if the compilation
/// fails or if the source code contains compilation errors.
///
/// [executable] is expected to contain a path to the dart source file and
/// a package_config file.
///
/// [serverInfoFile] is the location that should be checked to find an existing
/// Resident Frontend Compiler. If one does not exist, a server is created and
/// its address and port information is written to this file location.
///
/// [args] is the [ArgResults] object that is created by the DartDev commands.
/// This is where the optional path override for the serverInfoFile is passed
/// in.
///
/// [compileRequestGenerator] is applied to produce a request for the Resident
/// Frontend Server.
Future<DartExecutableWithPackageConfig> generateKernel(
  DartExecutableWithPackageConfig executable,
  File serverInfoFile,
  ArgResults args,
  CompileRequestGeneratorCallback compileRequestGenerator, {
  required bool quiet,
  bool aot = false,
  String? nativeAssetsYaml,
}) async {
  // Locates the package_config.json and cached kernel file, makes sure the
  // resident frontend server is up and running, and computes a kernel.
  await ensureCompilationServerIsRunning(serverInfoFile, quiet: quiet);

  final packageRoot = _packageRootFor(executable);
  final packageConfig = packageRoot != null
      ? p.join(packageRoot, packageConfigName)
      : null;

  final canonicalizedExecutablePath = p.canonicalize(executable.executable);
  final cachedDillPath = computeCachedDillAndCompilerOptionsPaths(
    canonicalizedExecutablePath,
  ).cachedDillPath;

  Map<String, dynamic> result;
  try {
    result = await sendAndReceiveResponse(
      compileRequestGenerator(
        executable: canonicalizedExecutablePath,
        outputDill: cachedDillPath,
        packages: packageConfig,
        args: args,
        nativeAssetsYaml: nativeAssetsYaml,
      ),
      serverInfoFile,
    );
  } on FileSystemException catch (e) {
    throw FrontendCompilerException._(e.message, CompilationIssue.serverError);
  }
  if (!result[responseSuccessString]) {
    if (result.containsKey(responseErrorString)) {
      throw FrontendCompilerException._(
        result[responseErrorString],
        CompilationIssue.serverError,
      );
    } else {
      throw FrontendCompilerException._(
        (result[responseOutputString] as List<dynamic>).join('\n'),
        CompilationIssue.compilationError,
      );
    }
  }
  return DartExecutableWithPackageConfig(
    executable: cachedDillPath,
    packageConfig: packageConfig,
  );
}

/// Ensures that a Resident Frontend Compiler associated with [serverInfoFile]
/// will be running at the point when the future returned by this function
/// completes. Throws a [FrontendCompilerException] if starting the server
/// fails.
Future<void> ensureCompilationServerIsRunning(
  File serverInfoFile, {
  required bool quiet,
}) async {
  if (serverInfoFile.existsSync()) {
    final residentCompilerInfo = ResidentCompilerInfo.fromFile(serverInfoFile);
    if (residentCompilerInfo.sdkHash != null &&
        isValidSdkHash(residentCompilerInfo.sdkHash!)) {
      // There is already a Resident Frontend Compiler associated with
      // [serverInfoFile] that is running and compatible with the Dart SDK that
      // the user is currently using.
      return;
    } else {
      if (!quiet) {
        log.stderr(
          'The Dart SDK has been upgraded or downgraded since the Resident '
          'Frontend Compiler was started, so the Resident Frontend Compiler will '
          'now be restarted for compatibility reasons.',
        );
      }
      await shutDownOrForgetResidentFrontendCompiler(serverInfoFile);
    }
  }
  try {
    Directory(p.dirname(serverInfoFile.path)).createSync(recursive: true);
    final Process frontendServerProcess;
    if (File(sdk.frontendServerAotSnapshot).existsSync()) {
      frontendServerProcess = await Process.start(
        sdk.dartAotRuntime,
        [
          sdk.frontendServerAotSnapshot,
          '--resident-info-file-name=${serverInfoFile.absolute.path}',
        ],
        workingDirectory: homeDir?.path,
        mode: ProcessStartMode.detachedWithStdio,
      );
    } else {
      throw StateError('Unable to find snapshot for frontend server');
    }

    final serverOutput = String.fromCharCodes(
      await frontendServerProcess.stdout.first,
    ).trim();
    if (serverOutput.startsWith('Error')) {
      throw StateError(serverOutput);
    }
    if (!quiet) {
      // Prints the server's address and port information
      log.stdout(serverOutput);
      log.stdout('');
      log.stdout(
        'Run dart compilation-server shutdown to terminate the process.',
      );
    }
  } catch (e) {
    throw FrontendCompilerException._(
      e.toString(),
      CompilationIssue.serverCreationError,
    );
  }
}

/// Returns the path to the root of the [executable]'s package, or null
/// if it is a standalone dart file.
String? _packageRootFor(DartExecutableWithPackageConfig executable) {
  Directory currentDirectory = Directory(
    p.dirname(p.canonicalize(executable.executable)),
  );

  while (currentDirectory.parent.path != currentDirectory.path) {
    if (File(p.join(currentDirectory.path, packageConfigName)).existsSync()) {
      return currentDirectory.path;
    }
    currentDirectory = currentDirectory.parent;
  }
  return null;
}

/// Indicates the type of issue encountered with the
/// Resident Frontend Compiler
enum CompilationIssue {
  /// Communication with the Resident Frontend Compiler failed.
  serverError,

  /// The Resident Frontend Compiler failed to launch
  serverCreationError,

  /// There were compilation errors in the Dart source code.
  compilationError,

  /// Resident mode is only supported for sources within Dart packages
  standaloneProgramError,
}

/// Indicates an error with the Resident Frontend Compiler.
class FrontendCompilerException implements Exception {
  final String message;
  final CompilationIssue issue;

  FrontendCompilerException._(this.message, this.issue);

  @override
  String toString() {
    return 'FrontendCompilerException: $message';
  }
}
