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

import 'package:source_maps/source_maps.dart' hide Printer;
import 'package:source_span/source_span.dart' show SourceLocation;
import 'js_ast.dart';

class NodeEnd {
  final SourceLocation end;
  NodeEnd(this.end);
  toString() => '#<NodeEnd $end>';
}

class NodeSpan {
  final SourceLocation start, end;
  NodeSpan(this.start, this.end);
  toString() => '#<NodeSpan $start to $end>';
}

class HoverComment {
  final SourceLocation start, end;
  final Expression expression;
  HoverComment(this.expression, this.start, this.end);
  toString() => '#<HoverComment `$expression` @ $start to $end>';
}

class SourceMapPrintingContext extends SimpleJavaScriptPrintingContext {
  /// Current line in the buffer.
  int _line = 0;

  /// Current column in the buffer.
  int _column = 0;

  /// The source_maps builder we write JavaScript code to.
  final sourceMap = SourceMapBuilder();

  /// The last marked line in the buffer.
  int _previousDartOffset = -1;

  SourceLocation _pendingDartOffset;
  SourceLocation _pendingJSLocation;

  @override
  void emit(String code) {
    var chars = code.runes.toList();
    var length = chars.length;
    for (int i = 0; i < length; i++) {
      var c = chars[i];
      if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) {
        // Return not followed by line-feed is treated as a new line.
        _line++;
        _column = 0;
      } else {
        _column++;
      }
    }
    super.emit(code);
  }

  @override
  void enterNode(Node node) {
    var srcInfo = node.sourceInformation;
    if (srcInfo == null) return;

    SourceLocation dartStart;
    if (srcInfo is SourceLocation) {
      dartStart = srcInfo;
    } else if (srcInfo is NodeSpan) {
      dartStart = srcInfo.start;
    } else if (srcInfo is HoverComment) {
      emit('/*');
      _mark(srcInfo.start);
      srcInfo.expression.accept(printer);
      _mark(srcInfo.end);
      emit('*/');
    } else if (srcInfo is! NodeEnd) {
      throw StateError(
          'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>');
    }

    if (dartStart != null) {
      if (node is Expression) {
        _markExpressionStart(dartStart);
      } else {
        _mark(dartStart);
      }
    }
  }

  @override
  void exitNode(Node node) {
    if (node is! Expression) _flushPendingMarks();

    var srcInfo = node.sourceInformation;
    if (srcInfo == null) return;

    SourceLocation dartEnd;
    if (srcInfo is NodeSpan) {
      dartEnd = srcInfo.end;
    } else if (srcInfo is NodeEnd) {
      dartEnd = srcInfo.end;
    } else if (srcInfo is! SourceLocation && srcInfo is! HoverComment) {
      throw StateError(
          'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>');
    }

    if (dartEnd != null) {
      if (node is Fun || node is Method || node is NamedFunction) {
        // Mark the exit point of a function. V8 steps to the end of a function
        // at its exit, so this provides a mapping for that location.
        int column = _column - 1;
        if (column >= 0) {
          // Adjust the colum, because any ending brace or semicolon is already in
          // the output.
          var jsEnd =
              SourceLocation(buffer.length - 1, line: _line, column: column);
          _mark(dartEnd, jsEnd);
        }
      } else {
        _mark(dartEnd);
      }
    }
  }

  /// Marks that we entered a Dart node at this offset.
  ///
  /// Multiple nested Dart expressions will appear to start at the same Dart
  /// location, but they can have different JavaScript locations. For example:
  ///
  ///     get foo => _foo.bar && _baz;
  ///     //         ^^^^^^^^^^^^^^^^ binary-op, JS code `dart.test(...) && ...`
  ///     //         ^^^^^^^^         property access, JS code `this[_foo].bar`
  ///     //         ^^^^             identifier, JS code `this[_foo]`
  ///
  /// To ensure hover works, we must not include `dart.test` at the start of
  /// `_foo`. Also to ensure `_foo` and `_foo.bar` works, we must mark the end
  /// of `_foo`.
  void _markExpressionStart(SourceLocation dartOffset) {
    if (_pendingDartOffset != dartOffset) _flushPendingMarks();
    _pendingDartOffset = dartOffset;
    _pendingJSLocation = _getJSLocation();
  }

  /// Mark any pending marks from [_markExpressionStart].
  ///
  /// This ensures we get the innermost JS offset for a given Dart offset.
  void _flushPendingMarks() {
    var pending = _pendingDartOffset;
    if (pending != null) {
      _markInternal(pending, _pendingJSLocation);
      _pendingDartOffset = null;
      _pendingJSLocation = null;
    }
  }

  void _mark(SourceLocation dartLocation, [SourceLocation jsLocation]) {
    _flushPendingMarks();
    jsLocation ??= _getJSLocation();
    _markInternal(dartLocation, jsLocation);
  }

  void _markInternal(SourceLocation dartLocation, SourceLocation jsLocation) {
    // Don't mark the same JS location to two different Dart locations.
    if (_previousDartOffset == dartLocation.offset) return;
    _previousDartOffset = dartLocation.offset;
    sourceMap.addLocation(dartLocation, jsLocation, null);
  }

  SourceLocation _getJSLocation() =>
      SourceLocation(buffer.length, line: _line, column: _column);
}

const int _LF = 10;
const int _CR = 13;
