// 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 'package:dwds/src/utilities/domain.dart';
import 'package:dwds/src/utilities/objects.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

/// The regular expressions used to filter out temp variables.
/// Needs to be kept in sync with SDK repo.
///
/// TODO(annagrin) - use an alternative way to identify
/// synthetic variables.
/// Issue: https://github.com/dart-lang/sdk/issues/44262
final ddcTemporaryVariableRegExp = RegExp(
  // Starts with t$
  r'^t\$'
  // followed by anything
  r'.*'
  // or,
  r'|'
  // anything that contains the sequence '$35'.
  r'.*\$35.*',
);
final ddcTemporaryTypeVariableRegExp = RegExp(r'^__t[\$\w*]+$');

/// Temporary variable regex before SDK changes for patterns.
/// TODO(annagrin): remove after dart 3.0 is stable.
final previousDdcTemporaryVariableRegExp = RegExp(
  r'^(t[0-9]+\$?[0-9]*|__t[\$\w*]+)$',
);

const ddcAsyncScope = 'asyncScope';
const ddcCapturedAsyncScope = 'capturedAsyncScope';

/// Find the visible Dart variables from a JS Scope Chain, coming from the
/// scopeChain attribute of a Chrome CallFrame corresponding to [frame].
///
/// See chromedevtools.github.io/devtools-protocol/tot/Debugger#type-CallFrame.
Future<List<Property>> visibleVariables({
  required AppInspectorInterface inspector,
  required WipCallFrame frame,
}) async {
  final allProperties = <Property>[];

  if (frame.thisObject.type != 'undefined') {
    allProperties.add(Property({'name': 'this', 'value': frame.thisObject}));
  }

  // TODO: Try and populate all the property info for the scopes in one backend
  // call. Along with some other optimizations (caching classRef lookups), we'd
  // end up averaging one backend call per frame.

  // Iterate to least specific scope last to help preserve order in the local
  // variables view when stepping.
  for (final scope in filterScopes(frame).reversed) {
    final objectId = scope.object.objectId;
    if (objectId != null) {
      final properties = await inspector.getProperties(objectId);
      allProperties.addAll(properties);
    }
  }

  if (frame.returnValue != null && frame.returnValue!.type != 'undefined') {
    allProperties.add(Property({'name': 'return', 'value': frame.returnValue}));
  }

  // DDC's async lowering hoists variable declarations into scope objects. We
  // create one scope object per Dart scope (skipping scopes containing no
  // declarations). If a Dart scope is captured by a Dart closure the
  // JS scope object will also be captured by the compiled JS closure.
  //
  // For debugging purposes we unpack these scope objects into the set of
  // available properties to recreate the Dart context at any given point.

  final capturedAsyncScopes = [
    ...allProperties.where(
      (p) => p.name?.startsWith(ddcCapturedAsyncScope) ?? false,
    ),
  ];

  if (capturedAsyncScopes.isNotEmpty) {
    // If we are in a local function within an async function, we should use the
    // available captured scopes. These will contain all the variables captured
    // by the closure. We only close over variables used within the closure.
    for (final scopeObject in capturedAsyncScopes) {
      final scopeObjectId = scopeObject.value?.objectId;
      if (scopeObjectId == null) continue;
      final scopeProperties = await inspector.getProperties(scopeObjectId);
      allProperties.addAll(scopeProperties);
      allProperties.remove(scopeObject);
    }
  } else {
    // Otherwise we are in the async function body itself. Unpack the available
    // async scopes. Scopes we have not entered may already have a scope object
    // declared but the object will not have any values in it yet.
    final asyncScopes = [
      ...allProperties.where((p) => p.name?.startsWith(ddcAsyncScope) ?? false),
    ];
    for (final scopeObject in asyncScopes) {
      final scopeObjectId = scopeObject.value?.objectId;
      if (scopeObjectId == null) continue;
      final scopeProperties = await inspector.getProperties(scopeObjectId);
      allProperties.addAll(scopeProperties);
      allProperties.remove(scopeObject);
    }
  }

  allProperties.removeWhere((property) {
    final value = property.value;
    if (value == null) return true;

    final type = value.type;
    if (type == 'undefined') return true;

    final description = value.description ?? '';
    final name = property.name ?? '';

    // TODO(#786) Handle these correctly rather than just suppressing them.
    // We should never see a raw JS class. The only case where this happens is a
    // Dart generic function, where the type arguments get passed in as
    // parameters. Hide those.
    return (type == 'function' && description.startsWith('class ')) ||
        previousDdcTemporaryVariableRegExp.hasMatch(name) ||
        ddcTemporaryVariableRegExp.hasMatch(name) ||
        ddcTemporaryTypeVariableRegExp.hasMatch(name) ||
        (type == 'object' && description == 'dart.LegacyType.new');
  });

  return allProperties;
}

/// Filters the provided frame scopes to those that are pertinent for Dart
/// debugging.
List<WipScope> filterScopes(WipCallFrame frame) {
  final scopes = frame.getScopeChain().toList();
  // Remove outer scopes up to and including the Dart SDK.
  while (scopes.isNotEmpty &&
      !(scopes.last.name?.startsWith('load__') ?? false)) {
    scopes.removeLast();
  }
  if (scopes.isNotEmpty) scopes.removeLast();
  return scopes;
}
