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

library dart2js.library_loader;

import 'dart:async';

import 'package:front_end/src/fasta/kernel/utils.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;

import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
import 'package:kernel/target/targets.dart' hide DiagnosticReporter;

import '../../compiler_new.dart' as api;
import '../commandline_options.dart' show Flags;
import '../common/tasks.dart' show CompilerTask, Measurer;
import '../common.dart';
import '../options.dart';
import '../util/sink_adapter.dart';

import 'front_end_adapter.dart';
import 'dart2js_target.dart' show Dart2jsTarget;

/// A task that produces the kernel IR representation of the application.
///
/// It supports loading both .dart source files or pre-compiled .dill files.
/// When given .dart source files, it invokes the common front-end (CFE)
/// to produce the corresponding kernel IR representation.
class KernelLoaderTask extends CompilerTask {
  final DiagnosticReporter _reporter;

  final api.CompilerInput _compilerInput;
  final api.CompilerOutput _compilerOutput;

  final CompilerOptions _options;

  /// Shared state between compilations.
  fe.InitializedCompilerState initializedCompilerState;

  // TODO(johnniwinther): Remove this when #34942 is fixed.
  /// Force in-memory serialization/deserialization of the loaded component.
  ///
  /// This is used for testing.
  bool forceSerialization = false;

  KernelLoaderTask(this._options, this._compilerInput, this._compilerOutput,
      this._reporter, Measurer measurer)
      : initializedCompilerState = _options.kernelInitializedCompilerState,
        super(measurer);

  @override
  String get name => 'kernel loader';

  /// Loads an entire Kernel [Component] from a file on disk.
  Future<KernelResult> load(Uri resolvedUri) {
    return measure(() async {
      String targetName =
          _options.compileForServer ? "dart2js_server" : "dart2js";

      // We defer selecting the platform until we've resolved the null safety
      // mode.
      String getPlatformFilename() {
        String platform = targetName;
        if (!_options.useLegacySubtyping) {
          platform += "_nnbd_strong";
        }
        platform += "_platform.dill";
        return platform;
      }

      ir.Component component;
      List<Uri> moduleLibraries = const [];
      var isDill = resolvedUri.path.endsWith('.dill') ||
          resolvedUri.path.endsWith('.gdill') ||
          resolvedUri.path.endsWith('.mdill');

      void inferNullSafetyMode(bool isSound) {
        if (_options.nullSafetyMode == NullSafetyMode.unspecified) {
          _options.nullSafetyMode =
              isSound ? NullSafetyMode.sound : NullSafetyMode.unsound;
        }
      }

      void validateNullSafetyMode() {
        assert(_options.nullSafetyMode != NullSafetyMode.unspecified);
      }

      if (isDill) {
        component = ir.Component();
        Future<void> read(Uri uri) async {
          api.Input input = await _compilerInput.readFromUri(uri,
              inputKind: api.InputKind.binary);
          BinaryBuilder(input.data).readComponent(component);
        }

        await read(resolvedUri);
        if (_options.modularMode) {
          moduleLibraries =
              component.libraries.map((lib) => lib.importUri).toList();
        }

        var isStrongDill =
            component.mode == ir.NonNullableByDefaultCompiledMode.Strong;
        var incompatibleNullSafetyMode =
            isStrongDill ? NullSafetyMode.unsound : NullSafetyMode.sound;
        if (_options.nullSafetyMode == incompatibleNullSafetyMode) {
          var dillMode = isStrongDill ? 'sound' : 'unsound';
          var option =
              isStrongDill ? Flags.noSoundNullSafety : Flags.soundNullSafety;
          throw ArgumentError("$resolvedUri was compiled with $dillMode null "
              "safety and is incompatible with the '$option' option");
        }
        inferNullSafetyMode(isStrongDill);
        validateNullSafetyMode();

        // Modular compiles do not include the platform on the input dill
        // either.
        if (_options.platformBinaries != null) {
          var platformUri =
              _options.platformBinaries.resolve(getPlatformFilename());
          // Modular analysis can be run on the sdk by providing directly the
          // path to the platform.dill file. In that case, we do not load the
          // platform file implicitly.
          // TODO(joshualitt): Change how we detect this case so it is less
          // brittle.
          if (platformUri != resolvedUri) await read(platformUri);
        }
        if (_options.dillDependencies != null) {
          for (Uri dependency in _options.dillDependencies) {
            await read(dependency);
          }
        }

        // This is not expected to be null when creating a whole-program .dill
        // file, but needs to be checked for modular inputs.
        if (component.mainMethod == null && !_options.modularMode) {
          // TODO(sigmund): move this so that we use the same error template
          // from the CFE.
          _reporter.reportError(_reporter.createMessage(NO_LOCATION_SPANNABLE,
              MessageKind.GENERIC, {'text': "No 'main' method found."}));
          return null;
        }
      } else {
        bool verbose = false;
        Target target =
            Dart2jsTarget(targetName, TargetFlags(), options: _options);
        fe.FileSystem fileSystem = CompilerFileSystem(_compilerInput);
        fe.Verbosity verbosity = _options.verbosity;
        fe.DiagnosticMessageHandler onDiagnostic =
            (fe.DiagnosticMessage message) {
          if (fe.Verbosity.shouldPrint(verbosity, message)) {
            reportFrontEndMessage(_reporter, message);
          }
        };
        fe.CompilerOptions options = fe.CompilerOptions()
          ..target = target
          ..librariesSpecificationUri = _options.librariesSpecificationUri
          ..packagesFileUri = _options.packageConfig
          ..explicitExperimentalFlags = _options.explicitExperimentalFlags
          ..verbose = verbose
          ..fileSystem = fileSystem
          ..onDiagnostic = onDiagnostic
          ..verbosity = verbosity;
        bool isLegacy =
            await fe.uriUsesLegacyLanguageVersion(resolvedUri, options);
        inferNullSafetyMode(!isLegacy);

        List<Uri> dependencies = [];
        if (_options.platformBinaries != null) {
          dependencies
              .add(_options.platformBinaries.resolve(getPlatformFilename()));
        }
        if (_options.dillDependencies != null) {
          dependencies.addAll(_options.dillDependencies);
        }

        initializedCompilerState = fe.initializeCompiler(
            initializedCompilerState,
            target,
            _options.librariesSpecificationUri,
            dependencies,
            _options.packageConfig,
            explicitExperimentalFlags: _options.explicitExperimentalFlags,
            nnbdMode: _options.useLegacySubtyping
                ? fe.NnbdMode.Weak
                : fe.NnbdMode.Strong,
            invocationModes: _options.cfeInvocationModes,
            verbosity: verbosity);
        component = await fe.compile(initializedCompilerState, verbose,
            fileSystem, onDiagnostic, resolvedUri);
        if (component == null) return null;
        validateNullSafetyMode();
      }

      if (_options.cfeOnly) {
        measureSubtask('serialize dill', () {
          _reporter.log('Writing dill to ${_options.outputUri}');
          api.BinaryOutputSink dillOutput =
              _compilerOutput.createBinarySink(_options.outputUri);
          BinaryOutputSinkAdapter irSink = BinaryOutputSinkAdapter(dillOutput);
          BinaryPrinter printer = BinaryPrinter(irSink);
          printer.writeComponentFile(component);
          irSink.close();
        });
      }

      if (forceSerialization) {
        // TODO(johnniwinther): Remove this when #34942 is fixed.
        List<int> data = serializeComponent(component);
        component = ir.Component();
        BinaryBuilder(data).readComponent(component);
      }
      return _toResult(component, moduleLibraries);
    });
  }

  KernelResult _toResult(ir.Component component, List<Uri> moduleLibraries) {
    Uri rootLibraryUri = null;
    Iterable<ir.Library> libraries = component.libraries;
    if (!_options.modularMode && component.mainMethod != null) {
      var root = component.mainMethod.enclosingLibrary;
      rootLibraryUri = root.importUri;

      // Filter unreachable libraries: [Component] was built by linking in the
      // entire SDK libraries, not all of them are used. We include anything
      // that is reachable from `main`. Note that all internal libraries that
      // the compiler relies on are reachable from `dart:core`.
      var seen = Set<Library>();
      search(ir.Library current) {
        if (!seen.add(current)) return;
        for (ir.LibraryDependency dep in current.dependencies) {
          search(dep.targetLibrary);
        }
      }

      search(root);

      // Libraries dependencies do not show implicit imports to `dart:core`.
      var dartCore = component.libraries.firstWhere((lib) {
        return lib.importUri.scheme == 'dart' && lib.importUri.path == 'core';
      });
      search(dartCore);

      libraries = libraries.where(seen.contains);
    }
    return KernelResult(component, rootLibraryUri,
        libraries.map((lib) => lib.importUri).toList(), moduleLibraries);
  }
}

/// Result of invoking the CFE to produce the kernel IR.
class KernelResult {
  final ir.Component component;

  /// The [Uri] of the root library containing main.
  /// Note: rootLibraryUri will be null for some modules, for example in the
  /// case of dependent libraries processed modularly.
  final Uri rootLibraryUri;

  /// Returns the [Uri]s of all libraries that have been loaded that are
  /// reachable from the [rootLibraryUri].
  ///
  /// Note that [component] may contain some libraries that are excluded here.
  final Iterable<Uri> libraries;

  /// When running only dart2js modular analysis, returns the [Uri]s for
  /// libraries loaded in the input module.
  ///
  /// This excludes other libraries reachable from them that were loaded as
  /// dependencies. The result of [moduleLibraries] is always a subset of
  /// [libraries].
  final Iterable<Uri> moduleLibraries;

  KernelResult(this.component, this.rootLibraryUri, this.libraries,
      this.moduleLibraries);

  @override
  String toString() =>
      'root=$rootLibraryUri,libraries=$libraries,module=$moduleLibraries';
}
