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

import 'package:kernel/ast.dart' as ir;
import '../common.dart';
import '../elements/entities.dart';
import '../js/js.dart' show JavaScriptNodeSourceInformation;
import '../serialization/serialization.dart';
import '../universe/call_structure.dart';
import '../js_model/element_map.dart';
import 'position_information.dart';

/// Interface for passing source information, for instance for use in source
/// maps, through the backend.
abstract class SourceInformation extends JavaScriptNodeSourceInformation {
  const SourceInformation();

  static SourceInformation readFromDataSource(DataSourceReader source) {
    int hasSourceInformation = source.readInt();
    if (hasSourceInformation == 1) {
      return const SourceMappedMarker();
    } else {
      assert(hasSourceInformation == 2);
      return PositionSourceInformation.readFromDataSource(source);
    }
  }

  static void writeToDataSink(
    DataSinkWriter sink,
    SourceInformation sourceInformation,
  ) {
    if (sourceInformation is SourceMappedMarker) {
      sink.writeInt(1);
    } else {
      sink.writeInt(2);
      PositionSourceInformation positionSourceInformation =
          sourceInformation as PositionSourceInformation;
      positionSourceInformation.writeToDataSinkInternal(sink);
    }
  }

  SourceSpan get sourceSpan;

  /// The source location associated with the start of the JS node.
  SourceLocation? get startPosition => null;

  /// The source location associated with an inner of the JS node.
  ///
  /// The inner position is for instance `foo()` in `o.foo()`.
  SourceLocation? get innerPosition => null;

  /// The source location associated with the end of the JS node.
  SourceLocation? get endPosition => null;

  /// A list containing start, inner, and end positions.
  List<SourceLocation> get sourceLocations;

  /// A list of inlining context locations.
  List<FrameContext>? get inliningContext => null;

  /// Return a short textual representation of the source location.
  String get shortText;
}

/// Context information about inlined calls.
///
/// This is associated with SourceInformation objects to be able to emit
/// precise data about inlining that can then be used by deobfuscation tools
/// when reconstructing a source stack from a production stack trace.
class FrameContext {
  static const String tag = 'frame-context';

  /// Location of the call that was inlined.
  final SourceInformation callInformation;

  /// Name of the method that was inlined.
  final String inlinedMethodName;

  FrameContext(this.callInformation, this.inlinedMethodName);

  factory FrameContext.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    SourceInformation callInformation = source
        .readIndexedNoCache<SourceInformation>(
          () => SourceInformation.readFromDataSource(source),
        );
    String inlinedMethodName = source.readString();
    source.end(tag);
    return FrameContext(callInformation, inlinedMethodName);
  }

  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeIndexed<SourceInformation>(
      callInformation,
      (SourceInformation sourceInformation) =>
          SourceInformation.writeToDataSink(sink, sourceInformation),
    );
    sink.writeString(inlinedMethodName);
    sink.end(tag);
  }

  @override
  String toString() => "(FrameContext: $callInformation, $inlinedMethodName)";
}

/// Strategy for creating, processing and applying [SourceInformation].
class SourceInformationStrategy {
  const SourceInformationStrategy();

  /// Called when the [JsToElementMap] is available.
  ///
  /// The [JsToElementMap] is used by some source information strategies to
  /// extract member details relevant in the source-map generation process.
  void onElementMapAvailable(JsToElementMap elementMap) {}

  /// Create a [SourceInformationBuilder] for [member].
  SourceInformationBuilder createBuilderForContext(
    covariant MemberEntity member,
  ) {
    return SourceInformationBuilder();
  }

  /// Generate [SourceInformation] marker for non-preamble code.
  SourceInformation? buildSourceMappedMarker() => null;

  /// Called when compilation has completed.
  void onComplete() {}
}

/// Interface for generating [SourceInformation].
class SourceInformationBuilder {
  const SourceInformationBuilder();

  /// Create a [SourceInformationBuilder] for [member] with additional inlining
  /// [context].
  SourceInformationBuilder forContext(
    covariant MemberEntity member,
    SourceInformation? context,
  ) => this;

  /// Generate [SourceInformation] for the declaration of the [member].
  SourceInformation? buildDeclaration(covariant MemberEntity member) => null;

  /// Generate [SourceInformation] for the stub of [callStructure] for [member].
  SourceInformation? buildStub(
    covariant FunctionEntity function,
    CallStructure callStructure,
  ) => null;

  /// Generate [SourceInformation] for the generic [node].
  @Deprecated("Use SourceInformationFactory")
  SourceInformation? buildGeneric(ir.Node node) => null;

  /// Generate [SourceInformation] for an instantiation of a class using [node]
  /// for the source position.
  SourceInformation? buildCreate(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the return [node].
  SourceInformation? buildReturn(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for an implicit return in [element].
  SourceInformation? buildImplicitReturn(covariant MemberEntity element) =>
      null;

  /// Generate [SourceInformation] for the loop [node].
  SourceInformation? buildLoop(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for a read access like `a.b`.
  SourceInformation? buildGet(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for a write access like `a.b = 3`.
  SourceInformation? buildSet(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for a call in [node].
  SourceInformation? buildCall(ir.Node receiver, ir.Node call) => null;

  /// Generate [SourceInformation] for the if statement in [node].
  SourceInformation? buildIf(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the block statement in [node].
  SourceInformation? buildBlock(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the constructor invocation in [node].
  SourceInformation? buildNew(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the throw in [node].
  SourceInformation? buildThrow(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the assert in [node].
  SourceInformation? buildAssert(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the assignment in [node].
  SourceInformation? buildAssignment(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the variable declaration inserted as
  /// first statement of a function.
  SourceInformation? buildVariableDeclaration() => null;

  /// Generate [SourceInformation] for the await [node].
  SourceInformation? buildAwait(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the yield or yield* [node].
  SourceInformation? buildYield(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for async/await boiler plate code.
  SourceInformation? buildAsyncBody() => null;

  /// Generate [SourceInformation] for exiting async/await code.
  SourceInformation? buildAsyncExit() => null;

  /// Generate [SourceInformation] for an invocation of a foreign method.
  SourceInformation? buildForeignCode(ir.Node node) => null;

  /// Generate [SourceInformation] for a string interpolation of [node].
  SourceInformation? buildStringInterpolation(ir.Node node) => null;

  /// Generate [SourceInformation] for the for-in `iterator` access in [node].
  SourceInformation? buildForInIterator(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the for-in `moveNext` call in [node].
  SourceInformation? buildForInMoveNext(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the for-in `current` access in [node].
  SourceInformation? buildForInCurrent(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the for-in variable assignment in [node].
  SourceInformation? buildForInSet(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the operator `[]` access in [node].
  SourceInformation? buildIndex(ir.Node node) => null;

  /// Generate [SourceInformation] for the operator `[]=` assignment in [node].
  SourceInformation? buildIndexSet(ir.Node node) => null;

  /// Generate [SourceInformation] for the binary operation in [node].
  SourceInformation? buildBinary(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the unary operation in [node].
  SourceInformation? buildUnary(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the try statement in [node].
  SourceInformation? buildTry(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the unary operator in [node].
  SourceInformation? buildCatch(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the is-test in [node].
  SourceInformation? buildIs(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the as-cast in [node].
  SourceInformation? buildAs(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the switch statement [node].
  SourceInformation? buildSwitch(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the switch case in [node].
  SourceInformation? buildSwitchCase(ir.Node node) => null;

  /// Generate [SourceInformation] for the list literal in [node].
  SourceInformation? buildListLiteral(ir.TreeNode node) => null;

  /// Generate [SourceInformation] for the break/continue in [node].
  SourceInformation? buildGoto(ir.TreeNode node) => null;
}

/// A location in a source file.
abstract class SourceLocation {
  static const String tag = 'source-location';

  const SourceLocation();

  /// The absolute URI of the source file of this source location.

  // TODO(48820): [sourceUri] is nullable due to `NoSourceLocationMarker`. We
  // would not need nullability of we could replace all
  // `NoSourceLocationMarker`s with `null`, or rearranged the `SourceLocation`
  // class hierarchy. `NoSourceLocationMarker` and `null` have different effects
  // on the generated source-map files.
  Uri? get sourceUri;

  /// The character offset of the this source location into the source file.
  int get offset;

  /// The 1-based line number of the [offset].
  int get line;

  /// The 1-based column number of the [offset] with its line.
  int get column;

  /// The name associated with this source location, if any.
  String? get sourceName;

  static SourceLocation readFromDataSource(DataSourceReader source) {
    int format = source.readInt();
    if (format == 0) {
      return const NoSourceLocationMarker();
    } else {
      source.begin(tag);
      Uri sourceUri = source.readUri();
      String sourceName = source.readStringOrNull()!;
      final locationSource = source.sourceLookup.lookupSource(sourceUri);
      final hasLocation = format > 1;
      int line = ir.TreeNode.noOffset;
      int column = ir.TreeNode.noOffset;
      if (hasLocation) {
        final lineLower = format - 2;
        final lineUpper = source.readInt();
        line = (lineUpper << 6) | lineLower;
        column = source.readInt();
      }
      source.end(tag);
      return _ConcreteSourceLocation(locationSource, sourceName, line, column);
    }
  }

  static void writeToDataSink(
    DataSinkWriter sink,
    SourceLocation sourceLocation,
  ) {
    if (sourceLocation is NoSourceLocationMarker) {
      sink.writeInt(0);
    } else {
      final column = sourceLocation.column;
      final line = sourceLocation.line;
      final hasLocation = line != ir.TreeNode.noOffset;
      // There are 2 formats in this case:
      // 1) The location has no offset so we only need a URI and name. Don't
      //    write any line/column info.
      // 2) The location has an offset so we use the 'format' to encode the
      //    bottom bits of the line and write the rest of the line and column
      //    separately as compact uint30 numbers.
      if (!hasLocation) {
        sink.writeInt(1);
      } else {
        sink.writeInt((line & 0x3f) + 2);
      }
      sink.begin(tag);
      sink.writeUri(sourceLocation.sourceUri!);
      sink.writeStringOrNull(sourceLocation.sourceName);
      if (hasLocation) {
        sink.writeInt(line >> 6);
        sink.writeInt(column);
      }
      sink.end(tag);
    }
  }

  @override
  int get hashCode {
    return sourceUri.hashCode * 17 +
        offset.hashCode * 19 +
        sourceName.hashCode * 23;
  }

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    return other is SourceLocation &&
        sourceUri == other.sourceUri &&
        offset == other.offset &&
        sourceName == other.sourceName;
  }

  String get shortText => '${sourceUri?.pathSegments.last}:[$line,$column]';

  @override
  String toString() => '$sourceUri:[$line,$column]';
}

/// A location in a source file encoded as a kernel [ir.Source] object and a
/// line/column encoded into a single 64 bit int.
class _ConcreteSourceLocation extends SourceLocation {
  final ir.Source _source;
  final int _lineColumn;

  _ConcreteSourceLocation(this._source, this.sourceName, int line, int column)
    : _lineColumn = (line << 32) | column;

  @override
  Uri get sourceUri => _source.fileUri!;

  @override
  int get offset => _source.getOffset(line, column);

  @override
  int get line => _lineColumn >>> 32;

  @override
  int get column => _lineColumn & 0xFFFFFFFF;

  @override
  final String sourceName;

  @override
  String get shortText => '${sourceUri.pathSegments.last}:[$line,$column]';

  @override
  String toString() => '$sourceUri:[$line,$column]';
}

/// Compute the source map name for [element]. If [callStructure] is non-null
/// it is used to name the parameter stub for [element].
// TODO(johnniwinther): Merge this with `computeKernelElementNameForSourceMaps`
// when the old frontend is removed.
String? computeElementNameForSourceMaps(
  Entity element, [
  CallStructure? callStructure,
]) {
  if (element is ClassEntity) {
    return element.name;
  }
  if (element is MemberEntity) {
    final enclosingClass = element.enclosingClass;
    String suffix = computeStubSuffix(callStructure);
    if (element is ConstructorEntity || element is ConstructorBodyEntity) {
      String className = enclosingClass!.name;
      if (element.name == '') {
        return className;
      }
      return '$className.${element.name}$suffix';
    }
    if (enclosingClass != null) {
      if (enclosingClass.isClosure) {
        return computeElementNameForSourceMaps(enclosingClass, callStructure);
      }
      return '${enclosingClass.name}.${element.name}$suffix';
    }
    return '${element.name}$suffix';
  }
  // TODO(redemption): Create element names from kernel locals and closures.
  return element.name;
}

/// Compute the suffix used for a parameter stub for [callStructure].
String computeStubSuffix(CallStructure? callStructure) {
  if (callStructure == null) return '';
  StringBuffer sb = StringBuffer();
  sb.write(r'[function-entry$');
  sb.write(callStructure.positionalArgumentCount);
  if (callStructure.namedArguments.isNotEmpty) {
    sb.write(r'$');
    sb.write(callStructure.getOrderedNamedArguments().join(r'$'));
  }
  sb.write(']');
  return sb.toString();
}

class NoSourceLocationMarker extends SourceLocation {
  const NoSourceLocationMarker();

  @override
  Uri? get sourceUri => null;

  @override
  int get column => 0;

  @override
  int get line => 0;

  @override
  int get offset => 0;

  @override
  String? get sourceName => null;

  String get shortName => '<no-location>';

  @override
  String toString() => '<no-location>';
}

/// Information tracked about inlined frames.
///
/// Dart2js adds an extension to source-map files to track where calls are
/// inlined. This information is used to improve the precision of tools that
/// deobfuscate production stack traces.
class FrameEntry {
  /// For push operations, the location of the inlining call, otherwise null.
  final SourceLocation? pushLocation;

  /// For push operations, the inlined method name, otherwise null.
  final String? inlinedMethodName;

  /// Whether a pop is the last pop that makes the inlining stack empty.
  final bool isEmptyPop;

  FrameEntry.push(this.pushLocation, this.inlinedMethodName)
    : isEmptyPop = false;

  FrameEntry.pop(this.isEmptyPop)
    : pushLocation = null,
      inlinedMethodName = null;

  bool get isPush => pushLocation != null;
  bool get isPop => pushLocation == null;
}

class SourceLookup {
  final Map<Uri, ir.Source> _map;

  SourceLookup(ir.Component component) : _map = component.uriToSource;

  ir.Source lookupSource(Uri uri) {
    return _map[uri]!;
  }
}
