// Copyright (c) 2019, 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 'dart:async';

import 'package:dwds/src/debugging/inspector.dart';

import '../utilities/domain.dart';
import '../utilities/shared.dart';
import '../utilities/wrapped_service.dart';
import 'metadata.dart';

/// Keeps track of Dart libraries available in the running application.
class LibraryHelper extends Domain {
  /// Map of library ID to [Library].
  final _librariesById = <String, Library>{};

  /// Map of libraryRef ID to [LibraryRef].
  final _libraryRefsById = <String, LibraryRef>{};

  LibraryHelper(AppInspector Function() provider) : super(provider);

  /// Returns all libraryRefs in the app.
  ///
  /// Note this can return a cached result.
  Future<List<LibraryRef>> get libraryRefs async {
    if (_libraryRefsById.isNotEmpty) return _libraryRefsById.values.toList();
    var expression = '''
      (function() {
        $getLibraries
        return libs;
      })()
     ''';
    var result = await inspector.remoteDebugger.sendCommand('Runtime.evaluate',
        params: {'expression': expression, 'returnByValue': true});
    handleErrorIfPresent(result, evalContents: expression);
    var libraries = List<String>.from(result.result['result']['value'] as List);
    // Filter out any non-Dart libraries, which basically means the .bootstrap
    // library from build_web_runners.
    var dartLibraries = libraries
        .where((name) => name.startsWith('dart:') || name.endsWith('.dart'));
    for (var library in dartLibraries) {
      var ref = LibraryRef(id: library, name: library, uri: library);
      _libraryRefsById[ref.id] = ref;
    }
    return _libraryRefsById.values.toList();
  }

  Future<Library> libraryFor(LibraryRef libraryRef) async {
    var library = _librariesById[libraryRef.id];
    if (library != null) return library;
    return _librariesById[libraryRef.id] = await _constructLibrary(libraryRef);
  }

  Future<LibraryRef> libraryRefFor(String objectId) async {
    if (_libraryRefsById.isEmpty) await libraryRefs;
    return _libraryRefsById[objectId];
  }

  Future<Library> _constructLibrary(LibraryRef libraryRef) async {
    // Fetch information about all the classes in this library.
    var expression = '''
    (function() {
      ${getLibrarySnippet(libraryRef.uri)}
      var result = {};
      var classes = Object.values(Object.getOwnPropertyDescriptors(library))
        .filter((p) => 'value' in p)
        .map((p) => p.value)
        .filter((l) => l && sdkUtils.isType(l));
      var classList = classes.map(function(clazz) {
        var descriptor = {
          'name': clazz.name,
          'dartName': sdkUtils.typeName(clazz)
        };
        return descriptor;
      });
      result['classes'] = classList;
      return result;
    })()
    ''';
    var result = await inspector.remoteDebugger.sendCommand('Runtime.evaluate',
        params: {'expression': expression, 'returnByValue': true});
    handleErrorIfPresent(result, evalContents: expression);
    var classDescriptors = (result.result['result']['value']['classes'] as List)
        .cast<Map<String, Object>>();
    var classRefs = classDescriptors.map<ClassRef>((classDescriptor) {
      var classMetaData = ClassMetaData(
          jsName: classDescriptor['name'],
          libraryId: libraryRef.id,
          dartName: classDescriptor['dartName']);
      return classMetaData.classRef;
    }).toList();
    return Library(
        name: libraryRef.name,
        uri: libraryRef.uri,
        debuggable: true,
        dependencies: [],
        scripts: await inspector.scriptRefs,
        variables: [],
        functions: [],
        classes: classRefs,
        id: libraryRef.id);
  }
}
