// Copyright (c) 2013, 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.

/// A library for compiling Dart code and manipulating analyzer parse trees.
import 'dart:async';
import 'dart:io';

import 'package:analyzer/dart/analysis/context_builder.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:frontend_server_client/frontend_server_client.dart';
import 'package:path/path.dart' as p;

import 'exceptions.dart';
import 'io.dart';
import 'log.dart' as log;

class AnalysisContextManager {
  static final sessions = <String, AnalysisContextManager>{};

  final String packagePath;
  final AnalysisSession _session;

  factory AnalysisContextManager(String packagePath) => sessions.putIfAbsent(
      packagePath, () => AnalysisContextManager._(packagePath));

  AnalysisContextManager._(this.packagePath)
      : _session = ContextBuilder()
            .createContext(
              contextRoot: ContextLocator().locateRoots(
                includedPaths: [p.absolute(p.normalize(packagePath))],
                optionsFile:
                    // We don't want to take 'analysis_options.yaml' files into
                    // account. So we replace it with an empty file.
                    Platform.isWindows ? r'C:\NUL' : '/dev/null',
              ).first,
            )
            .currentSession;

  /// Parse the file with the given [path] into AST.
  ///
  /// One of the containing directories must be used to create analysis
  /// contexts using [createContextsForDirectory]. Throws [StateError] if
  /// this has not been done.
  ///
  /// Throws [AnalyzerErrorGroup] is the file has parsing errors.
  CompilationUnit parse(String path) {
    path = p.normalize(p.absolute(path));
    var parseResult = _session.getParsedUnit(path);
    if (parseResult is ParsedUnitResult) {
      if (parseResult.errors.isNotEmpty) {
        throw AnalyzerErrorGroup(parseResult.errors);
      }
      return parseResult.unit;
    } else {
      throw StateError('Unable to parse $path, ${parseResult.runtimeType}');
    }
  }

  /// Return import and export directives in the file with the given [path].
  ///
  /// Throws [AnalyzerErrorGroup] is the file has parsing errors.
  List<UriBasedDirective> parseImportsAndExports(String path) {
    var unit = parse(path);
    var uriDirectives = <UriBasedDirective>[];
    for (var directive in unit.directives) {
      if (directive is UriBasedDirective) {
        uriDirectives.add(directive);
      }
    }
    return uriDirectives;
  }
}

/// An error class that contains multiple [AnalysisError]s.
class AnalyzerErrorGroup implements Exception {
  final List<AnalysisError> errors;

  AnalyzerErrorGroup(this.errors);

  String get message => toString();

  @override
  String toString() => errors.join('\n');
}

/// Precompiles the Dart executable at [executablePath].
///
/// If the compilation succeeds it is saved to a kernel file at [outputPath].
///
/// If compilation fails, the output is cached at [incrementalDillOutputPath].
///
/// Whichever of [incrementalDillOutputPath] and [outputPath] already exists is
/// used to initialize the compiler run.
///
/// The [packageConfigPath] should point at the package config file to be used
/// for `package:` uri resolution.
///
/// The [name] is used to describe the executable in logs and error messages.
///
/// The [additionalSources], if provided, instruct the compiler to include
/// additional source files into compilation even if they are not referenced
/// from the main library.
///
/// The [nativeAssets], if provided, instruct the compiler include a native
/// assets map.
Future<void> precompile({
  required String executablePath,
  required String incrementalDillPath,
  required String name,
  required String outputPath,
  required String packageConfigPath,
  List<String> additionalSources = const [],
  String? nativeAssets,
}) async {
  ensureDir(p.dirname(outputPath));
  ensureDir(p.dirname(incrementalDillPath));

  const platformDill = 'lib/_internal/vm_platform_strong.dill';
  final sdkRoot = p.relative(p.dirname(p.dirname(Platform.resolvedExecutable)));
  String? tempDir;
  FrontendServerClient? client;
  try {
    tempDir = createTempDir(p.dirname(incrementalDillPath), 'tmp');
    // To avoid potential races we copy the incremental data to a temporary file
    // for just this compilation.
    final temporaryIncrementalDill =
        p.join(tempDir, '${p.basename(incrementalDillPath)}.temp');
    try {
      if (fileExists(incrementalDillPath)) {
        copyFile(incrementalDillPath, temporaryIncrementalDill);
      } else if (fileExists(outputPath)) {
        copyFile(outputPath, temporaryIncrementalDill);
      }
    } on FileSystemException {
      // Not able to copy existing file, compilation will start from scratch.
    }

    client = await FrontendServerClient.start(
      executablePath,
      temporaryIncrementalDill,
      platformDill,
      sdkRoot: sdkRoot,
      packagesJson: packageConfigPath,
      additionalSources: additionalSources,
      nativeAssets: nativeAssets,
      printIncrementalDependencies: false,
    );
    final result = await client.compile();

    final highlightedName = log.bold(name);
    if (result.errorCount == 0) {
      log.message('Built $highlightedName.');
      // By using rename we ensure atomicity. An external observer will either
      // see the old or the new snapshot.
      final parent = File(outputPath).parent;
      if (!await parent.exists()) {
        await parent.create(recursive: true);
      }
      renameFile(temporaryIncrementalDill, outputPath);
    } else {
      // By using rename we ensure atomicity. An external observer will either
      // see the old or the new snapshot.
      renameFile(temporaryIncrementalDill, incrementalDillPath);
      // If compilation failed we don't want to leave an incorrect snapshot.
      tryDeleteEntry(outputPath);

      throw ApplicationException(
          log.yellow('Failed to build $highlightedName:\n') +
              result.compilerOutputLines.join('\n'));
    }
  } finally {
    client?.kill();
    if (tempDir != null) {
      tryDeleteEntry(tempDir);
    }
  }
}
