// 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 (var 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 (var 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);
  }
}
