// Copyright 2022 The Chromium Authors. 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:package_config/package_config.dart';
import 'package:path/path.dart' as p;
import 'package:pub/pub.dart';

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

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

/// Uses the resident frontend compiler to compute a kernel file for
/// [executable]. Throws a [FrontendCompilerException] if the compilation
/// fails or if the source code contians 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, {
  bool aot = false,
}) async {
  // Locates the package_config.json and cached kernel file, makes sure the
  // resident frontend server is up and running, and computes a kernel.
  final packageRoot = _packageRootFor(executable);
  if (packageRoot == null) {
    throw FrontendCompilerException._(
        'resident mode is only supported for Dart packages.',
        CompilationIssue.standaloneProgramError);
  }
  await _ensureCompileServerIsRunning(args, serverInfoFile);
  // TODO: allow custom package paths with a --packages flag
  final packageConfig = await _resolvePackageConfig(executable, packageRoot);
  final cachedKernel = _cachedKernelPath(executable.executable, packageRoot);
  Map<String, dynamic> result;
  try {
    result = await sendAndReceiveResponse(
      compileRequestGenerator(
        executable: p.canonicalize(executable.executable),
        outputDill: cachedKernel,
        packages: packageConfig,
        args: args,
      ),
      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: cachedKernel,
    packageConfig: packageConfig,
  );
}

/// Returns the absolute path to [executable]'s cached kernel file.
/// Throws a [FrontendCompilerException] if the cached kernel cannot be
/// created.
String _cachedKernelPath(String executable, String packageRoot) {
  final executableDirPath = p.canonicalize(p.dirname(executable));
  var cachedKernelDirectory = p.join(
    packageRoot,
    '.dart_tool',
    dartdevKernelCache,
  );

  final subdirectoryList =
      executableDirPath.replaceFirst(packageRoot, '').split(p.separator);
  for (var directory in subdirectoryList) {
    cachedKernelDirectory = p.join(cachedKernelDirectory, directory);
  }

  try {
    Directory(cachedKernelDirectory).createSync(recursive: true);
  } catch (e) {
    throw FrontendCompilerException._(
      e.toString(),
      CompilationIssue.serverError,
    );
  }
  return p.canonicalize(
    p.join(
      cachedKernelDirectory,
      '${p.basename(executable)}-${sdk.version}.dill',
    ),
  );
}

/// Ensures that the Resident Frontend Compiler is running, starting it if
/// necessary. Throws a [FrontendCompilerException] if starting the server
/// fails.
Future<void> _ensureCompileServerIsRunning(
  ArgResults args,
  File serverInfoFile,
) async {
  if (serverInfoFile.existsSync()) {
    return;
  }
  try {
    Directory(p.dirname(serverInfoFile.path)).createSync(recursive: true);
    // TODO replace this with the AOT executable when that is built.
    final frontendServerProcess = await Process.start(
      sdk.dart,
      [
        sdk.frontendServerSnapshot,
        '--resident-info-file-name=${serverInfoFile.path}'
      ],
      workingDirectory: home,
      mode: ProcessStartMode.detachedWithStdio,
    );

    final serverOutput =
        String.fromCharCodes(await frontendServerProcess.stdout.first);
    if (serverOutput.startsWith('Error')) {
      throw StateError(serverOutput);
    }
    print(serverOutput); // Prints the server's address and port information
  } 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, 'pubspec.yaml')).existsSync() ||
        File(p.join(currentDirectory.path, packageConfigName)).existsSync()) {
      return currentDirectory.path;
    }
    currentDirectory = currentDirectory.parent;
  }
  return null;
}

/// Resolves the absolute path to [packageRoot]'s package_config.json file,
/// returning null if the package does not contain one, or if the source
/// being compiled is a standalone dart script not inside a package.
Future<String?> _resolvePackageConfig(
    DartExecutableWithPackageConfig executable, String packageRoot) async {
  final packageConfig = await findPackageConfigUri(
    Uri.file(p.canonicalize(executable.executable)),
    recurse: true,
    onError: (_) {},
  );
  if (packageConfig != null) {
    final dotPackageFile = File(p.join(packageRoot, '.packages'));
    final packageConfigFile = File(p.join(packageRoot, packageConfigName));
    return packageConfigFile.existsSync()
        ? packageConfigFile.path
        : dotPackageFile.path;
  }
  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';
  }
}
