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

/// Standalone utility that manages loading source maps for all Dart scripts
/// on the page compiled with DDC.
///
/// Example JavaScript usage:
/// $dartStackTraceUtility.addLoadedListener(function() {
///   // All Dart source maps are now loaded. It is now safe to start your
///   // Dart application compiled with DDC.
///   dart_library.start('your_dart_application');
/// })
///
/// If $dartStackTraceUtility is set, the dart:core StackTrace class calls
/// $dartStackTraceUtility.mapper(someJSStackTrace)
/// to apply source maps.
///
/// This utility can be compiled to JavaScript using Dart2JS while the rest
/// of the application is compiled with DDC or could be compiled with DDC.
@JS()
library;

// ignore: deprecated_member_use
import 'package:js/js.dart';
import 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart';
import 'package:source_span/source_span.dart';
import 'package:stack_trace/stack_trace.dart';

import 'source_map_stack_trace.dart';

typedef ReadyCallback = void Function();

/// Global object DDC uses to see if a stack trace utility has been registered.
@JS(r'$dartStackTraceUtility')
external set dartStackTraceUtility(DartStackTraceUtility value);

@JS(r'$dartLoader.rootDirectories')
external List get rootDirectories;

typedef StackTraceMapper = String Function(String stackTrace);
typedef SourceMapProvider = dynamic Function(String modulePath);
typedef SetSourceMapProvider = void Function(SourceMapProvider);

@JS()
@anonymous
class DartStackTraceUtility {
  external factory DartStackTraceUtility({
    StackTraceMapper? mapper,
    SetSourceMapProvider? setSourceMapProvider,
  });
}

@JS('JSON.stringify')
external String _stringify(dynamic json);

/// Source mapping that is waits to parse source maps until they match the uri
/// of a requested source map.
///
/// This improves startup performance compared to using MappingBundle directly.
/// The unparsed data for the source maps must still be loaded before
/// LazyMapping is used.
class LazyMapping extends Mapping {
  final MappingBundle _bundle = MappingBundle();
  final SourceMapProvider _provider;

  LazyMapping(this._provider);

  List toJson() => _bundle.toJson();

  @override
  SourceMapSpan? spanFor(
    int line,
    int column, {
    Map<String, SourceFile>? files,
    String? uri,
  }) {
    if (uri == null) {
      throw ArgumentError.notNull('uri');
    }

    if (!_bundle.containsMapping(uri)) {
      var rawMap = _provider(uri);
      if (rawMap != null) {
        var strMap = rawMap is String ? rawMap : _stringify(rawMap);
        var mapping = parse(strMap) as SingleMapping;
        mapping
          ..targetUrl = uri
          ..sourceRoot = '${p.dirname(uri)}/';
        _bundle.addMapping(mapping);
      }
    }
    var span = _bundle.spanFor(line, column, files: files, uri: uri);
    // TODO(jacobr): we shouldn't have to filter out invalid sourceUrl entries
    // here.
    if (span == null || span.start.sourceUrl == null) return null;
    var pathSegments = span.start.sourceUrl!.pathSegments;
    if (pathSegments.isNotEmpty && pathSegments.last == 'null') return null;
    return span;
  }
}

LazyMapping? _mapping;

List<String> roots = rootDirectories.map((s) => '$s').toList();

String mapper(String rawStackTrace) {
  var mapping = _mapping;
  if (mapping == null) {
    // This should not happen if the user has waited for the ReadyCallback
    // to start the application.
    throw StateError('Source maps are not done loading.');
  }
  var trace = Trace.parse(rawStackTrace);
  return mapStackTrace(mapping, trace, roots: roots).toString();
}

void setSourceMapProvider(SourceMapProvider provider) {
  _mapping = LazyMapping(provider);
}

void main() {
  // Register with DDC.
  dartStackTraceUtility = DartStackTraceUtility(
    mapper: allowInterop(mapper),
    setSourceMapProvider: allowInterop(setSourceMapProvider),
  );
}
