// Copyright (c) 2020, 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/config/tool_configuration.dart';
import 'package:dwds/src/debugging/dart_scope.dart';
import 'package:dwds/src/debugging/debugger.dart';
import 'package:dwds/src/debugging/location.dart';
import 'package:dwds/src/debugging/modules.dart';
import 'package:dwds/src/services/expression_compiler.dart';
import 'package:dwds/src/services/javascript_builder.dart';
import 'package:dwds/src/utilities/conversions.dart';
import 'package:dwds/src/utilities/domain.dart';
import 'package:dwds/src/utilities/objects.dart' as chrome;
import 'package:logging/logging.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

class EvaluationErrorKind {
  EvaluationErrorKind._();

  static const compilation = 'CompilationError';
  static const type = 'TypeError';
  static const reference = 'ReferenceError';
  static const internal = 'InternalError';
  static const asyncFrame = 'AsyncFrameError';
  static const invalidInput = 'InvalidInputError';
  static const loadModule = 'LoadModuleError';
}

/// ExpressionEvaluator provides functionality to evaluate dart expressions
/// from text user input in the debugger, using chrome remote debugger to
/// collect context for evaluation (scope, types, modules), and using
/// ExpressionCompilerInterface to compile dart expressions to JavaScript.
class ExpressionEvaluator {
  final String _entrypoint;
  final AppInspectorInterface _inspector;
  final Debugger _debugger;
  final Locations _locations;
  final Modules _modules;
  final ExpressionCompiler _compiler;
  final _logger = Logger('ExpressionEvaluator');
  bool _closed = false;

  /// Strip synthetic library name from compiler error messages.
  static final _syntheticNameFilterRegex = RegExp(
    'org-dartlang-debug:synthetic_debug_expression:.*:.*Error: ',
  );

  /// Find module path from the XHR call network error message received from chrome.
  ///
  /// Example:
  /// NetworkError: Failed to load `http://<hostname>.com/path/to/module.js?<cache_busting_token>`
  static final _loadModuleErrorRegex = RegExp(
    r".*Failed to load '.*\.com/(.*\.js).*",
  );

  ExpressionEvaluator(
    this._entrypoint,
    this._inspector,
    this._debugger,
    this._locations,
    this._modules,
    this._compiler,
  );

  /// Create and error with [severity] and [message]
  ///
  /// [severity] is one of kinds in [EvaluationErrorKind]
  RemoteObject createError(String severity, String message) {
    return RemoteObject(<String, String>{'type': severity, 'value': message});
  }

  void close() {
    _closed = true;
  }

  /// Evaluate dart expression inside a given library.
  ///
  /// Uses ExpressionCompiler interface to compile the expression to
  /// JavaScript and sends evaluate requests to chrome to calculate
  /// the final result.
  ///
  /// Returns remote object containing the result of evaluation or error.
  ///
  /// [isolateId] current isolate ID.
  /// [libraryUri] dart library to evaluate the expression in.
  /// [expression] dart expression to evaluate.
  Future<RemoteObject> evaluateExpression(
    String isolateId,
    String? libraryUri,
    String expression,
    Map<String, String>? scope,
  ) async {
    if (_closed) {
      return createError(
        EvaluationErrorKind.internal,
        'expression evaluator closed.',
      );
    }

    scope ??= {};

    if (expression.isEmpty) {
      return createError(EvaluationErrorKind.invalidInput, expression);
    }

    if (libraryUri == null) {
      return createError(EvaluationErrorKind.invalidInput, 'no library uri');
    }

    final module = await _modules.moduleForLibrary(libraryUri);
    if (module == null) {
      return createError(
        EvaluationErrorKind.internal,
        'no module for $libraryUri',
      );
    }

    // Wrap the expression in a lambda so we can call it as a function.
    expression = _createDartLambda(expression, scope.keys);
    _logger.finest('Evaluating "$expression" at $module');

    // Compile expression using an expression compiler, such as
    // frontend server or expression compiler worker.
    final compilationResult = await _compiler.compileExpressionToJs(
      isolateId,
      libraryUri.toString(),
      0,
      0,
      {},
      {},
      module,
      expression,
    );

    final isError = compilationResult.isError;
    final jsResult = compilationResult.result;
    if (isError) {
      return _formatCompilationError(jsResult);
    }

    // Strip try/catch incorrectly added by the expression compiler.
    final jsCode = _maybeStripTryCatch(jsResult);

    // Send JS expression to chrome to evaluate.
    var result = await _callJsFunction(jsCode, scope);
    result = await _formatEvaluationError(result);

    _logger.finest('Evaluated "$expression" to "${result.json}"');
    return result;
  }

  /// Evaluate dart expression inside a given frame (function).
  ///
  /// Gets necessary context (types, scope, module names) data from chrome,
  /// uses ExpressionCompiler interface to compile the expression to
  /// JavaScript, and sends evaluate requests to chrome to calculate the
  /// final result.
  ///
  /// Returns remote object containing the result of evaluation or error.
  ///
  /// [isolateId] current isolate ID.
  /// [frameIndex] JavaScript frame to evaluate the expression in.
  /// [expression] dart expression to evaluate.
  /// [scope] additional scope to use in the expression as a map from
  ///   variable names to remote object IDs.
  ///
  /////////////////////////////////
  /// **Example - without scope**
  ///
  /// To evaluate a dart expression `e`, we perform the following:
  ///
  /// 1. compile dart expression `e` to JavaScript expression `jsExpr`
  ///    using the expression compiler (i.e. frontend server or expression
  ///    compiler worker).
  ///
  /// 2. create JavaScript wrapper expression, `jsWrapperExpr`, defined as
  ///
  ///    ```JavaScript
  ///    try {
  ///      jsExpr;
  ///    } catch (error) {
  ///      error.name + ": " + error.message;
  ///    }
  ///    ```
  ///
  /// 3. evaluate `JsExpr` using `Debugger.evaluateOnCallFrame` chrome API.
  ///
  /// //////////////////////////
  /// **Example - with scope**
  ///
  /// To evaluate a dart expression
  /// ```dart
  ///   this.t + a + x + y
  /// ```
  /// in a dart scope that defines `a` and `this`, and additional scope
  /// `x, y`, we perform the following:
  ///
  /// 1. compile dart function
  ///
  ///    ```dart
  ///    (x, y, a) { return this.t + a + x + y; }
  ///    ```
  ///
  ///    to JavaScript function
  ///
  ///    ```jsFunc```
  ///
  ///    using the expression compiler (i.e. frontend server or expression
  ///    compiler worker).
  ///
  /// 2. create JavaScript wrapper function, `jsWrapperFunc`, defined as
  ///
  ///    ```JavaScript
  ///    function (x, y, a, __t$this) {
  ///      try {
  ///        return function (x, y, a) {
  ///          return jsFunc(x, y, a);
  ///        }.bind(__t$this)(x, y, a);
  ///      } catch (error) {
  ///        return error.name + ": " + error.message;
  ///      }
  ///    }
  ///    ```
  ///
  /// 3. collect scope variable object IDs for total scope
  ///    (original frame scope from WipCallFrame + additional scope passed
  ///    by the user).
  ///
  /// 4. call `jsWrapperFunc` using `Runtime.callFunctionOn` chrome API
  ///    with scope variable object IDs passed as arguments.
  Future<RemoteObject> evaluateExpressionInFrame(
    String isolateId,
    int frameIndex,
    String expression,
    Map<String, String>? scope,
  ) async {
    scope ??= {};

    if (expression.isEmpty) {
      return createError(EvaluationErrorKind.invalidInput, expression);
    }

    // Get JS scope and current JS location.
    final jsFrame = _debugger.jsFrameForIndex(frameIndex);
    if (jsFrame == null) {
      return createError(
        EvaluationErrorKind.asyncFrame,
        'Expression evaluation in async frames '
        'is not supported. No frame with index $frameIndex.',
      );
    }

    final functionName = jsFrame.functionName;
    final jsLine = jsFrame.location.lineNumber;
    final jsScriptId = jsFrame.location.scriptId;
    final jsColumn = jsFrame.location.columnNumber;
    final frameScope = await _collectLocalFrameScope(jsFrame);

    // Find corresponding dart location and scope.
    final url = _debugger.urlForScriptId(jsScriptId);
    if (url == null) {
      return createError(
        EvaluationErrorKind.internal,
        'Cannot find url for JS script: $jsScriptId',
      );
    }
    final locationMap = await _locations.locationForJs(url, jsLine, jsColumn);
    if (locationMap == null) {
      return createError(
        EvaluationErrorKind.internal,
        'Cannot find Dart location for JS location: '
        'url: $url, '
        'function: $functionName, '
        'line: $jsLine, '
        'column: $jsColumn',
      );
    }

    final dartLocation = locationMap.dartLocation;
    final dartSourcePath = dartLocation.uri.serverPath;
    final libraryUri = await _modules.libraryForSource(dartSourcePath);
    if (libraryUri == null) {
      return createError(
        EvaluationErrorKind.internal,
        'no libraryUri for $dartSourcePath',
      );
    }

    final module = await _modules.moduleForLibrary(libraryUri.toString());
    if (module == null) {
      return createError(
        EvaluationErrorKind.internal,
        'no module for $libraryUri ($dartSourcePath)',
      );
    }

    _logger.finest(
      'Evaluating "$expression" at $module, '
      '$libraryUri:${dartLocation.line}:${dartLocation.column} '
      'with scope: $scope',
    );

    if (scope.isNotEmpty) {
      final totalScope = Map<String, String>.from(scope)..addAll(frameScope);
      expression = _createDartLambda(expression, totalScope.keys);
    }

    _logger.finest('Compiling "$expression"');

    // Compile expression using an expression compiler, such as
    // frontend server or expression compiler worker.
    //
    // TODO(annagrin): map JS locals to dart locals in the expression
    // and JS scope before passing them to the dart expression compiler.
    // Issue:  https://github.com/dart-lang/sdk/issues/40273
    final compilationResult = await _compiler.compileExpressionToJs(
      isolateId,
      libraryUri.toString(),
      dartLocation.line,
      dartLocation.column,
      {},
      frameScope.map((key, value) => MapEntry(key, key)),
      module,
      expression,
    );

    final isError = compilationResult.isError;
    final jsResult = compilationResult.result;
    if (isError) {
      return _formatCompilationError(jsResult);
    }

    // Strip try/catch incorrectly added by the expression compiler.
    final jsCode = _maybeStripTryCatch(jsResult);

    // Send JS expression to chrome to evaluate.
    var result =
        scope.isEmpty
            ? await _evaluateJsExpressionInFrame(frameIndex, jsCode)
            : await _callJsFunctionInFrame(
              frameIndex,
              jsCode,
              scope,
              frameScope,
            );

    result = await _formatEvaluationError(result);
    _logger.finest('Evaluated "$expression" to "${result.json}"');
    return result;
  }

  /// Call JavaScript [function] with [scope] on frame [frameIndex].
  ///
  /// Wrap the [function] in a lambda that takes scope variables as parameters.
  /// Send JS expression to chrome to evaluate in frame with [frameIndex]
  /// with the provided [scope].
  ///
  /// [frameIndex] is the index of the frame to call the function in.
  /// [function] is the JS function to evaluate.
  /// [scope] is the additional scope as a map from scope variables to
  ///   remote object IDs.
  /// [frameScope] is the original scope as a map from scope variables
  ///   to remote object IDs.
  Future<RemoteObject> _callJsFunctionInFrame(
    int frameIndex,
    String function,
    Map<String, String> scope,
    Map<String, String> frameScope,
  ) async {
    final totalScope = Map<String, String>.from(scope)..addAll(frameScope);
    final thisObject = await _debugger.evaluateJsOnCallFrameIndex(
      frameIndex,
      'this',
    );

    final thisObjectId = thisObject.objectId;
    if (thisObjectId != null) {
      totalScope['this'] = thisObjectId;
    }

    return _callJsFunction(function, totalScope);
  }

  /// Call the [function] with [scope] as arguments.
  ///
  /// Wrap the [function] in a lambda that takes scope variables as parameters.
  /// Send JS expression to chrome to evaluate with the provided [scope].
  ///
  /// [function] is the JS function to evaluate.
  /// [scope] is a map from scope variables to remote object IDs.
  Future<RemoteObject> _callJsFunction(
    String function,
    Map<String, String> scope,
  ) {
    final jsCode = _createEvalFunction(function, scope.keys);

    _logger.finest('Evaluating JS: "$jsCode" with scope: $scope');
    return _inspector.callFunction(jsCode, scope.values);
  }

  /// Evaluate JavaScript [expression] on frame [frameIndex].
  ///
  /// Wrap the [expression] in a try/catch expression to catch errors.
  /// Send JS expression to chrome to evaluate on frame [frameIndex].
  ///
  /// [frameIndex] is the index of the frame to call the function in.
  /// [expression] is the JS function to evaluate.
  Future<RemoteObject> _evaluateJsExpressionInFrame(
    int frameIndex,
    String expression,
  ) {
    final jsCode = _createEvalExpression(expression);

    _logger.finest('Evaluating JS: "$jsCode"');
    return _debugger.evaluateJsOnCallFrameIndex(frameIndex, jsCode);
  }

  static String? _getObjectId(RemoteObject? object) =>
      object?.objectId ?? dartIdFor(object?.value);

  RemoteObject _formatCompilationError(String error) {
    // Frontend currently gives a text message including library name
    // and function name on compilation error. Strip this information
    // since it shows synthetic names that are only used for temporary
    // debug library during expression evaluation.
    //
    // TODO(annagrin): modify frontend to avoid stripping dummy names
    // [issue 40449](https://github.com/dart-lang/sdk/issues/40449)
    if (error.startsWith('[')) {
      error = error.substring(1);
    }
    if (error.endsWith(']')) {
      error = error.substring(0, error.lastIndexOf(']'));
    }
    if (error.contains('InternalError: ')) {
      error = error.replaceAll('InternalError: ', '');
      return createError(EvaluationErrorKind.internal, error);
    }
    error = error.replaceAll(_syntheticNameFilterRegex, '');
    return createError(EvaluationErrorKind.compilation, error);
  }

  Future<RemoteObject> _formatEvaluationError(RemoteObject result) async {
    if (result.type == 'string') {
      var error = '${result.value}';
      if (error.startsWith('ReferenceError: ')) {
        error = error.replaceFirst('ReferenceError: ', '');
        return createError(EvaluationErrorKind.reference, error);
      } else if (error.startsWith('TypeError: ')) {
        error = error.replaceFirst('TypeError: ', '');
        return createError(EvaluationErrorKind.type, error);
      } else if (error.startsWith('NetworkError: ')) {
        var modulePath = _loadModuleErrorRegex.firstMatch(error)?.group(1);
        final module =
            modulePath != null
                ? await globalToolConfiguration.loadStrategy
                    .moduleForServerPath(_entrypoint, modulePath)
                : 'unknown';
        modulePath ??= 'unknown';
        error =
            'Module is not loaded : $module (path: $modulePath). '
            'Accessing libraries that have not yet been used in the '
            'application is not supported during expression evaluation.';
        return createError(EvaluationErrorKind.loadModule, error);
      }
    }
    return result;
  }

  /// Return local scope as a map from variable names to remote object IDs.
  ///
  /// [frame] is the current frame index.
  Future<Map<String, String>> _collectLocalFrameScope(
    WipCallFrame frame,
  ) async {
    final scope = <String, String>{};

    void collectVariables(Iterable<chrome.Property> variables) {
      for (final p in variables) {
        final name = p.name;
        final value = p.value;
        // TODO: null values represent variables optimized by v8.
        // Show that to the user.
        if (name != null && value != null && !_isUndefined(value)) {
          final objectId = _getObjectId(p.value);
          if (objectId != null) {
            scope[name] = objectId;
          }
        }
      }
    }

    // skip library and main scope
    final scopeChain = filterScopes(frame).reversed;
    for (final scope in scopeChain) {
      final objectId = scope.object.objectId;
      if (objectId != null) {
        final scopeProperties = await _inspector.getProperties(objectId);
        collectVariables(scopeProperties);
      }
    }

    return scope;
  }

  bool _isUndefined(RemoteObject value) => value.type == 'undefined';

  static String _createDartLambda(String expression, Iterable<String> params) =>
      '(${params.join(', ')}) { return $expression; }';

  /// Strip try/catch incorrectly added by the expression compiler.
  /// TODO: remove adding try/catch block in expression compiler.
  /// https://github.com/dart-lang/webdev/issues/1341, then remove
  /// this stripping code.
  static String _maybeStripTryCatch(String jsCode) {
    // Match the wrapping generated by the expression compiler exactly
    // so the matching does not succeed naturally after the wrapping is
    // removed:
    //
    // Expression compiler's wrapping:
    //
    // '\ntry {'
    // '\n  ($jsExpression('
    // '\n    $args'
    // '\n  ))'
    // '\n} catch (error) {'
    // '\n  error.name + ": " + error.message;'
    // '\n}';
    //
    final lines = jsCode.split('\n');
    if (lines.length > 5) {
      final tryLines = lines.getRange(0, 2).toList();
      final bodyLines = lines.getRange(2, lines.length - 3);
      final catchLines =
          lines.getRange(lines.length - 3, lines.length).toList();
      if (tryLines[0].isEmpty &&
          tryLines[1] == 'try {' &&
          catchLines[0] == '} catch (error) {' &&
          catchLines[1] == '  error.name + ": " + error.message;' &&
          catchLines[2] == '}') {
        return bodyLines.join('\n');
      }
    }
    return jsCode;
  }

  /// Create JS expression to pass to `Debugger.evaluateOnCallFrame`.
  static String _createEvalExpression(String expression) {
    final body = expression.split('\n').where((e) => e.isNotEmpty);

    return JsBuilder.createEvalExpression(body);
  }

  /// Create JS function  to invoke in `Runtime.callFunctionOn`.
  static String _createEvalFunction(String function, Iterable<String> params) {
    final body = function.split('\n').where((e) => e.isNotEmpty);

    return params.contains('this')
        ? JsBuilder.createEvalBoundFunction(body, params)
        : JsBuilder.createEvalStaticFunction(body, params);
  }
}
