// Copyright (c) 2015, 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.serialization.task;

import 'dart:async' show EventSink, Future;
import '../common.dart';
import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
import '../common/tasks.dart' show CompilerTask;
import '../common/work.dart' show ItemCompilationContext;
import '../compiler.dart' show Compiler;
import '../elements/elements.dart';
import '../enqueue.dart' show ResolutionEnqueuer;
import '../universe/world_impact.dart' show WorldImpact;
import 'json_serializer.dart';
import 'serialization.dart';
import 'system.dart';

/// A deserializer that can load a library element by reading it's information
/// from a serialized form.
abstract class LibraryDeserializer {
  /// Loads the [LibraryElement] associated with a library under [uri], or null
  /// if no serialized information is available for the given library.
  Future<LibraryElement> readLibrary(Uri uri);
}

/// Task that supports deserialization of elements.
class SerializationTask extends CompilerTask implements LibraryDeserializer {
  final Compiler compiler;
  SerializationTask(Compiler compiler)
      : compiler = compiler,
        super(compiler.measurer);

  DeserializerSystem deserializer;

  String get name => 'Serialization';

  /// If `true`, data must be retained to support serialization.
  // TODO(johnniwinther): Make this more precise in terms of what needs to be
  // retained, for instance impacts, resolution data etc.
  bool supportSerialization = false;

  /// If `true`, deserialized data is supported.
  bool get supportsDeserialization => deserializer != null;

  /// Returns the [LibraryElement] for [resolvedUri] if available from
  /// serialization.
  Future<LibraryElement> readLibrary(Uri resolvedUri) {
    if (deserializer == null) return new Future<LibraryElement>.value();
    return deserializer.readLibrary(resolvedUri);
  }

  /// Returns `true` if [element] has been deserialized.
  bool isDeserialized(Element element) {
    return deserializer != null && deserializer.isDeserialized(element);
  }

  bool hasResolutionImpact(Element element) {
    return deserializer != null && deserializer.hasResolutionImpact(element);
  }

  ResolutionImpact getResolutionImpact(Element element) {
    return deserializer != null
        ? deserializer.getResolutionImpact(element)
        : null;
  }

  /// Creates the [ResolutionWorkItem] for the deserialized [element].
  ResolutionWorkItem createResolutionWorkItem(
      Element element, ItemCompilationContext context) {
    assert(deserializer != null);
    assert(isDeserialized(element));
    return new DeserializedResolutionWorkItem(
        element, context, deserializer.computeWorldImpact(element));
  }

  bool hasResolvedAst(ExecutableElement element) {
    return deserializer != null ? deserializer.hasResolvedAst(element) : false;
  }

  ResolvedAst getResolvedAst(ExecutableElement element) {
    return deserializer != null ? deserializer.getResolvedAst(element) : null;
  }

  Serializer createSerializer(Iterable<LibraryElement> libraries) {
    return measure(() {
      assert(supportSerialization);

      Serializer serializer =
          new Serializer(shouldInclude: (e) => libraries.contains(e.library));
      SerializerPlugin backendSerializer =
          compiler.backend.serialization.serializer;
      serializer.plugins.add(backendSerializer);
      serializer.plugins.add(new ResolutionImpactSerializer(
          compiler.resolution, backendSerializer));
      serializer.plugins.add(new ResolvedAstSerializerPlugin(
          compiler.resolution, backendSerializer));

      for (LibraryElement library in libraries) {
        serializer.serialize(library);
      }
      return serializer;
    });
  }

  void serializeToSink(
      EventSink<String> sink, Iterable<LibraryElement> libraries) {
    measure(() {
      sink
        ..add(createSerializer(libraries)
            .toText(const JsonSerializationEncoder()))
        ..close();
    });
  }

  void deserializeFromText(Uri sourceUri, String serializedData) {
    measure(() {
      if (deserializer == null) {
        deserializer = new DeserializerSystemImpl(
            compiler, compiler.backend.impactTransformer);
      }
      DeserializerSystemImpl deserializerImpl = deserializer;
      DeserializationContext context = deserializerImpl.deserializationContext;
      Deserializer dataDeserializer = new Deserializer.fromText(
          context, sourceUri, serializedData, const JsonSerializationDecoder());
      context.deserializers.add(dataDeserializer);
    });
  }
}

/// A [ResolutionWorkItem] for a deserialized element.
///
/// This will not resolve the element but only compute the [WorldImpact].
class DeserializedResolutionWorkItem implements ResolutionWorkItem {
  final Element element;
  final ItemCompilationContext compilationContext;
  final WorldImpact worldImpact;
  bool _isAnalyzed = false;

  DeserializedResolutionWorkItem(
      this.element, this.compilationContext, this.worldImpact);

  @override
  bool get isAnalyzed => _isAnalyzed;

  @override
  WorldImpact run(Compiler compiler, ResolutionEnqueuer world) {
    _isAnalyzed = true;
    world.registerProcessedElement(element);
    return worldImpact;
  }
}

/// The interface for a system that supports deserialization of libraries and
/// elements.
abstract class DeserializerSystem {
  Future<LibraryElement> readLibrary(Uri resolvedUri);
  bool isDeserialized(Element element);
  bool hasResolvedAst(ExecutableElement element);
  ResolvedAst getResolvedAst(ExecutableElement element);
  bool hasResolutionImpact(Element element);
  ResolutionImpact getResolutionImpact(Element element);
  WorldImpact computeWorldImpact(Element element);
}
