// 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.

/// Data produced by dart2js when run with the `--dump-info` flag.
library dart2js_info.info;

import 'dart:collection';
import 'dart:convert';

import 'package:collection/collection.dart';

import 'src/measurements.dart';
import 'src/util.dart';

export 'src/measurements.dart';

part 'json_info_codec.dart';

/// Common interface to many pieces of information generated by the dart2js
/// compiler that are directly associated with an element (compilation unit,
/// library, class, function, or field).
abstract class Info {
  /// An identifier for the kind of information.
  InfoKind get kind;

  /// Name of the element associated with this info.
  String name;

  /// An id to uniquely identify this info among infos of the same [kind].
  // TODO(kevmoo) Consider removing `id` entirely. Make it an impl detail of
  //              the JSON encoder
  int get id;

  /// A globally unique id combining [kind] and [id] together.
  String get serializedId;

  /// Id used by the compiler when instrumenting code for code coverage.
  // TODO(sigmund): It would be nice if we could use the same id for
  // serialization and for coverage. Could we unify them?
  String coverageId;

  /// Bytes used in the generated code for the corresponding element.
  int size;

  /// Info of the enclosing element.
  Info parent;

  T accept<T>(InfoVisitor<T> visitor);
}

/// Common information used for most kind of elements.
// TODO(sigmund): add more:
//  - inputSize: bytes used in the Dart source program
abstract class BasicInfo implements Info {
  static final Set<int> _ids = new Set<int>();
  final InfoKind kind;

  int _id;
  // TODO(kevmoo) Make computation of id explicit and not on-demand.
  int get id {
    if (_id == null) {
      assert(this is LibraryInfo ||
          this is ConstantInfo ||
          this is OutputUnitInfo ||
          this.parent != null);

      if (this is ConstantInfo) {
        // No name and no parent, so `longName` isn't helpful
        assert(this.name == null);
        assert(this.parent == null);
        assert((this as ConstantInfo).code != null);
        // Instead, use the content of the code.
        _id = (this as ConstantInfo).code.hashCode;
      } else {
        _id = longName(this, useLibraryUri: true, forId: true).hashCode;
      }
      while (!_ids.add(_id)) {
        _id++;
      }
    }

    return _id;
  }

  String coverageId;
  int size;
  Info parent;

  String get serializedId => '${kindToString(kind)}/$id';

  String name;

  /// If using deferred libraries, where the element associated with this info
  /// is generated.
  OutputUnitInfo outputUnit;

  BasicInfo(this.kind, this.name, this.outputUnit, this.size, this.coverageId);

  BasicInfo._fromId(String serializedId)
      : kind = _kindFromSerializedId(serializedId),
        _id = _idFromSerializedId(serializedId);

  String toString() => '$serializedId $name [$size]';
}

/// Info associated with elements containing executable code (like fields and
/// methods)
abstract class CodeInfo implements Info {
  /// How does this function or field depend on others.
  final Set<DependencyInfo> uses = new SplayTreeSet<DependencyInfo>();
}

/// The entire information produced while compiling a program.
class AllInfo {
  /// Summary information about the program.
  ProgramInfo program;

  /// Information about each library processed by the compiler.
  List<LibraryInfo> libraries = <LibraryInfo>[];

  /// Information about each function (includes methods and getters in any
  /// library)
  List<FunctionInfo> functions = <FunctionInfo>[];

  /// Information about type defs in the program.
  List<TypedefInfo> typedefs = <TypedefInfo>[];

  /// Information about each class (in any library).
  List<ClassInfo> classes = <ClassInfo>[];

  /// Information about fields (in any class).
  List<FieldInfo> fields = <FieldInfo>[];

  /// Information about constants anywhere in the program.
  // TODO(sigmund): expand docs about canonicalization. We don't put these
  // inside library because a single constant can be used in more than one lib,
  // and we'll include it only once in the output.
  List<ConstantInfo> constants = <ConstantInfo>[];

  /// Information about closures anywhere in the program.
  List<ClosureInfo> closures = <ClosureInfo>[];

  /// Information about output units (should be just one entry if not using
  /// deferred loading).
  List<OutputUnitInfo> outputUnits = <OutputUnitInfo>[];

  /// Details about all deferred imports and what files would be loaded when the
  /// import is resolved.
  // TODO(sigmund): use a different format for dump-info. This currently emits
  // the same map that is created for the `--deferred-map` flag.
  Map<String, Map<String, dynamic>> deferredFiles;

  /// A new representation of dependencies from one info to another. An entry in
  /// this map indicates that an [Info] depends on another (e.g. a function
  /// invokes another). Please note that the data in this field might not be
  /// accurate yet (this is work in progress).
  Map<Info, List<Info>> dependencies = {};

  /// Major version indicating breaking changes in the format. A new version
  /// means that an old deserialization algorithm will not work with the new
  /// format.
  final int version = 5;

  /// Minor version indicating non-breaking changes in the format. A change in
  /// this version number means that the json parsing in this library from a
  /// previous will continue to work after the change. This is typically
  /// increased when adding new entries to the file format.
  // Note: the dump-info.viewer app was written using a json parser version 3.2.
  final int minorVersion = 1;

  AllInfo();

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitAll(this);
}

class ProgramInfo {
  FunctionInfo entrypoint;
  int size;
  String dart2jsVersion;
  DateTime compilationMoment;
  Duration compilationDuration;
  Duration toJsonDuration;
  Duration dumpInfoDuration;

  /// `true` if `noSuchMethod` is used.
  bool noSuchMethodEnabled;

  /// `true` if `Object.runtimeType` is used.
  bool isRuntimeTypeUsed;

  /// `true` if the `dart:isolate` library is in use.
  bool isIsolateInUse;

  /// `true` if `Function.apply` is used.
  bool isFunctionApplyUsed;

  /// `true` if `dart:mirrors` features are used.
  bool isMirrorsUsed;

  bool minified;

  ProgramInfo(
      {this.entrypoint,
      this.size,
      this.dart2jsVersion,
      this.compilationMoment,
      this.compilationDuration,
      this.toJsonDuration,
      this.dumpInfoDuration,
      this.noSuchMethodEnabled,
      this.isRuntimeTypeUsed,
      this.isIsolateInUse,
      this.isFunctionApplyUsed,
      this.isMirrorsUsed,
      this.minified});

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitProgram(this);
}

/// Info associated with a library element.
class LibraryInfo extends BasicInfo {
  /// Canonical uri that identifies the library.
  Uri uri;

  /// Top level functions defined within the library.
  final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[];

  /// Top level fields defined within the library.
  final List<FieldInfo> topLevelVariables = <FieldInfo>[];

  /// Classes defined within the library.
  final List<ClassInfo> classes = <ClassInfo>[];

  /// Typedefs defined within the library.
  final List<TypedefInfo> typedefs = <TypedefInfo>[];

  // TODO(sigmund): add here a list of parts. That can help us improve how we
  // encode source-span information in metrics (rather than include the uri on
  // each function, include an index into this list).

  /// Whether there is any information recorded for this library.
  bool get isEmpty =>
      topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty;

  LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size)
      : super(InfoKind.library, name, outputUnit, size, null);

  LibraryInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitLibrary(this);
}

/// Information about an output unit. Normally there is just one for the entire
/// program unless the application uses deferred imports, in which case there
/// would be an additional output unit per deferred chunk.
class OutputUnitInfo extends BasicInfo {
  /// The deferred imports that will load this output unit.
  List<String> imports = <String>[];

  OutputUnitInfo(String name, int size)
      : super(InfoKind.outputUnit, name, null, size, null);

  OutputUnitInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitOutput(this);
}

/// Information about a class element.
class ClassInfo extends BasicInfo {
  /// Whether the class is abstract.
  bool isAbstract;

  // TODO(sigmund): split static vs instance vs closures
  /// Functions (static or instance) defined in the class.
  final List<FunctionInfo> functions = <FunctionInfo>[];

  /// Fields defined in the class.
  // TODO(sigmund): currently appears to only be populated with instance fields,
  // but this should be fixed.
  final List<FieldInfo> fields = <FieldInfo>[];

  ClassInfo(
      {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0})
      : super(InfoKind.clazz, name, outputUnit, size, null);

  ClassInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitClass(this);
}

/// Information about a constant value.
// TODO(sigmund): add dependency data for ConstantInfo
class ConstantInfo extends BasicInfo {
  /// The actual generated code for the constant.
  String code;

  // TODO(sigmund): Add coverage support to constants?
  ConstantInfo({int size: 0, this.code, OutputUnitInfo outputUnit})
      : super(InfoKind.constant, null, outputUnit, size, null);

  ConstantInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitConstant(this);
}

/// Information about a field element.
class FieldInfo extends BasicInfo with CodeInfo {
  /// The type of the field.
  String type;

  /// The type inferred by dart2js's whole program analysis
  String inferredType;

  /// Nested closures seen in the field initializer.
  List<ClosureInfo> closures;

  /// The actual generated code for the field.
  String code;

  /// Whether this corresponds to a const field declaration.
  bool isConst;

  /// When [isConst] is true, the constant initializer expression.
  ConstantInfo initializer;

  FieldInfo(
      {String name,
      String coverageId,
      int size: 0,
      this.type,
      this.inferredType,
      this.closures,
      this.code,
      OutputUnitInfo outputUnit,
      this.isConst})
      : super(InfoKind.field, name, outputUnit, size, coverageId);

  FieldInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitField(this);
}

/// Information about a typedef declaration.
class TypedefInfo extends BasicInfo {
  /// The declared type.
  String type;

  TypedefInfo(String name, this.type, OutputUnitInfo outputUnit)
      : super(InfoKind.typedef, name, outputUnit, 0, null);

  TypedefInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitTypedef(this);
}

/// Information about a function or method.
class FunctionInfo extends BasicInfo with CodeInfo {
  static const int TOP_LEVEL_FUNCTION_KIND = 0;
  static const int CLOSURE_FUNCTION_KIND = 1;
  static const int METHOD_FUNCTION_KIND = 2;
  static const int CONSTRUCTOR_FUNCTION_KIND = 3;

  /// Kind of function (top-level function, closure, method, or constructor).
  int functionKind;

  /// Modifiers applied to this function.
  FunctionModifiers modifiers;

  /// Nested closures that appear within the body of this function.
  List<ClosureInfo> closures;

  /// The type of this function.
  String type;

  /// The declared return type.
  String returnType;

  /// The inferred return type.
  String inferredReturnType;

  /// Name and type information for each parameter.
  List<ParameterInfo> parameters;

  /// Side-effects.
  // TODO(sigmund): serialize more precisely, not just a string representation.
  String sideEffects;

  /// How many function calls were inlined into this function.
  int inlinedCount;

  /// The actual generated code.
  String code;

  /// Measurements collected for this function.
  Measurements measurements;

  FunctionInfo(
      {String name,
      String coverageId,
      OutputUnitInfo outputUnit,
      int size: 0,
      this.functionKind,
      this.modifiers,
      this.closures,
      this.type,
      this.returnType,
      this.inferredReturnType,
      this.parameters,
      this.sideEffects,
      this.inlinedCount,
      this.code,
      this.measurements})
      : super(InfoKind.function, name, outputUnit, size, coverageId);

  FunctionInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitFunction(this);
}

/// Information about a closure, also known as a local function.
class ClosureInfo extends BasicInfo {
  /// The function that is wrapped by this closure.
  FunctionInfo function;

  ClosureInfo(
      {String name, OutputUnitInfo outputUnit, int size: 0, this.function})
      : super(InfoKind.closure, name, outputUnit, size, null);

  ClosureInfo._(String serializedId) : super._fromId(serializedId);

  T accept<T>(InfoVisitor<T> visitor) => visitor.visitClosure(this);
}

/// Information about how a dependency is used.
class DependencyInfo implements Comparable<DependencyInfo> {
  /// The dependency, either a FunctionInfo or FieldInfo.
  final Info target;

  /// Either a selector mask indicating how this is used, or 'inlined'.
  // TODO(sigmund): split mask into an enum or something more precise to really
  // describe the dependencies in detail.
  final String mask;

  DependencyInfo(this.target, this.mask);

  int compareTo(DependencyInfo other) {
    var value = target.serializedId.compareTo(other.target.serializedId);
    if (value == 0) {
      value = mask.compareTo(other.mask);
    }
    return value;
  }

  bool operator ==(other) =>
      other is DependencyInfo &&
      target.serializedId == other.target.serializedId &&
      mask == other.mask;

  int get hashCode => target.serializedId.hashCode * 37 ^ mask.hashCode;
}

/// Name and type information about a function parameter.
class ParameterInfo {
  final String name;
  final String type;
  final String declaredType;

  ParameterInfo(this.name, this.type, this.declaredType);
}

/// Modifiers that may apply to methods.
class FunctionModifiers {
  final bool isStatic;
  final bool isConst;
  final bool isFactory;
  final bool isExternal;

  FunctionModifiers(
      {this.isStatic: false,
      this.isConst: false,
      this.isFactory: false,
      this.isExternal: false});
}

/// Possible values of the `kind` field in the serialized infos.
enum InfoKind {
  library,
  clazz,
  function,
  field,
  constant,
  outputUnit,
  typedef,
  closure,
}

String kindToString(InfoKind kind) {
  switch (kind) {
    case InfoKind.library:
      return 'library';
    case InfoKind.clazz:
      return 'class';
    case InfoKind.function:
      return 'function';
    case InfoKind.field:
      return 'field';
    case InfoKind.constant:
      return 'constant';
    case InfoKind.outputUnit:
      return 'outputUnit';
    case InfoKind.typedef:
      return 'typedef';
    case InfoKind.closure:
      return 'closure';
    default:
      return null;
  }
}

int _idFromSerializedId(String serializedId) =>
    int.parse(serializedId.substring(serializedId.indexOf('/') + 1));

InfoKind _kindFromSerializedId(String serializedId) =>
    kindFromString(serializedId.substring(0, serializedId.indexOf('/')));

InfoKind kindFromString(String kind) {
  switch (kind) {
    case 'library':
      return InfoKind.library;
    case 'class':
      return InfoKind.clazz;
    case 'function':
      return InfoKind.function;
    case 'field':
      return InfoKind.field;
    case 'constant':
      return InfoKind.constant;
    case 'outputUnit':
      return InfoKind.outputUnit;
    case 'typedef':
      return InfoKind.typedef;
    case 'closure':
      return InfoKind.closure;
    default:
      return null;
  }
}

/// A simple visitor for information produced by the dart2js compiler.
abstract class InfoVisitor<T> {
  T visitAll(AllInfo info);
  T visitProgram(ProgramInfo info);
  T visitLibrary(LibraryInfo info);
  T visitClass(ClassInfo info);
  T visitField(FieldInfo info);
  T visitConstant(ConstantInfo info);
  T visitFunction(FunctionInfo info);
  T visitTypedef(TypedefInfo info);
  T visitClosure(ClosureInfo info);
  T visitOutput(OutputUnitInfo info);
}

/// A visitor that recursively walks each portion of the program. Because the
/// info representation is redundant, this visitor only walks the structure of
/// the program and skips some redundant links. For example, even though
/// visitAll contains references to functions, this visitor only recurses to
/// visit libraries, then from each library we visit functions and classes, and
/// so on.
class RecursiveInfoVisitor extends InfoVisitor<Null> {
  visitAll(AllInfo info) {
    // Note: we don't visit functions, fields, classes, and typedefs because
    // they are reachable from the library info.
    info.libraries.forEach(visitLibrary);
    info.constants.forEach(visitConstant);
  }

  visitProgram(ProgramInfo info) {}

  visitLibrary(LibraryInfo info) {
    info.topLevelFunctions.forEach(visitFunction);
    info.topLevelVariables.forEach(visitField);
    info.classes.forEach(visitClass);
    info.typedefs.forEach(visitTypedef);
  }

  visitClass(ClassInfo info) {
    info.functions.forEach(visitFunction);
    info.fields.forEach(visitField);
  }

  visitField(FieldInfo info) {
    info.closures.forEach(visitClosure);
  }

  visitConstant(ConstantInfo info) {}

  visitFunction(FunctionInfo info) {
    info.closures.forEach(visitClosure);
  }

  visitTypedef(TypedefInfo info) {}
  visitOutput(OutputUnitInfo info) {}
  visitClosure(ClosureInfo info) {
    visitFunction(info.function);
  }
}
