// Copyright (c) 2023, 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:kernel/ast.dart';
import 'package:kernel/type_environment.dart';

import 'method_collector.dart';
import 'util.dart';

/// Expands inline JS calls to trampolines that call functions in the JS
/// runtime.
class InlineExpander {
  final StatefulStaticTypeContext _staticTypeContext;
  final CoreTypesUtil _util;
  final MethodCollector _methodCollector;
  late String _inlineJSImportName;
  bool _replaceProcedureWithInlineJS = false;

  InlineExpander(this._staticTypeContext, this._util, this._methodCollector);

  void enterProcedure() {
    // Under very restricted circumstances, we will make a procedure
    // external and clear it's body. See the description on
    // [expand] for more details.
    _replaceProcedureWithInlineJS = false;
  }

  void exitProcedure(Procedure node) {
    if (_replaceProcedureWithInlineJS) {
      node.isStatic = true;
      node.isExternal = true;
      node.function.body = null;
      _util.annotateProcedure(node, _inlineJSImportName, AnnotationType.import);
      _replaceProcedureWithInlineJS = false;
    }
  }

  Procedure? _tryGetEnclosingProcedure(TreeNode? node) {
    while (node is! Procedure) {
      node = node?.parent;
      if (node == null) {
        return null;
      }
    }
    return node;
  }

  /// We will replace the enclosing procedure if:
  ///   1) The enclosing procedure is static.
  ///   2) The enclosing procedure has a body with a single statement, and that
  ///      statement is just a [StaticInvocation] of the inline JS helper.
  ///   3) All of the arguments to `inlineJS` are [VariableGet]s. (this is
  ///      checked by [_expandInlineJS]).
  bool _shouldReplaceEnclosingProcedure(StaticInvocation node) {
    Procedure? enclosingProcedure = _tryGetEnclosingProcedure(node);
    if (enclosingProcedure == null) {
      return false;
    }
    Statement enclosingBody = enclosingProcedure.function.body!;
    Expression? expression;
    if (enclosingBody is ReturnStatement) {
      expression = enclosingBody.expression;
    } else if (enclosingBody is Block && enclosingBody.statements.length == 1) {
      Statement statement = enclosingBody.statements.single;
      if (statement is ExpressionStatement) {
        expression = statement.expression;
      } else if (statement is ReturnStatement) {
        expression = statement.expression;
      }
    }
    return expression == node;
  }

  /// Calls to the `JS` helper are replaced in one of two ways:
  ///   1) By a static invocation to an external stub method that imports
  ///      the JS function.
  ///   2) Under restricted circumstances the entire enclosing procedure will be
  ///      replaced by an external stub method that imports the JS function. See
  ///      [_shouldReplaceEnclosingProcedure] for more details.
  Expression expand(StaticInvocation node) {
    Arguments arguments = node.arguments;
    List<Expression> originalArguments = arguments.positional.sublist(1);
    List<VariableDeclaration> dartPositionalParameters = [];
    bool allArgumentsAreGet = true;
    for (int j = 0; j < originalArguments.length; j++) {
      Expression originalArgument = originalArguments[j];
      String parameterString = 'x$j';
      DartType type = originalArgument.getStaticType(_staticTypeContext);
      dartPositionalParameters.add(VariableDeclaration(parameterString,
          type: _toExternalType(type), isSynthesized: true));
      if (originalArgument is! VariableGet) {
        allArgumentsAreGet = false;
      }
    }

    assert(arguments.positional[0] is StringLiteral,
        "Code template must be a StringLiteral");
    String codeTemplate = (arguments.positional[0] as StringLiteral).value;
    String jsMethodName = _methodCollector.generateMethodName();
    _inlineJSImportName = 'dart2wasm.$jsMethodName';
    _replaceProcedureWithInlineJS =
        allArgumentsAreGet && _shouldReplaceEnclosingProcedure(node);
    Procedure dartProcedure;
    Expression result;
    if (_replaceProcedureWithInlineJS) {
      dartProcedure = _tryGetEnclosingProcedure(node)!;
      result = InvalidExpression("Unreachable");
    } else {
      dartProcedure = _methodCollector.addInteropProcedure(
          '|$jsMethodName',
          _inlineJSImportName,
          FunctionNode(null,
              positionalParameters: dartPositionalParameters,
              returnType: arguments.types.single),
          _util.inlineJSTarget.fileUri,
          AnnotationType.import,
          isExternal: true);
      result = StaticInvocation(dartProcedure, Arguments(originalArguments));
    }
    _methodCollector.addMethod(dartProcedure, jsMethodName, codeTemplate);
    return result;
  }

  // The `JS<foo>("...some js code ...", arg0, arg1)` expressions will produce
  // wasm imports. We want to only use types in those wasm imports that binaryen
  // allows under closed world assumptions (and not blindly use `arg<N>`s static
  // type).
  //
  // For now we special case `WasmArray<>` which we turn into a generic `array`
  // type (super type of all wasm arrays).
  DartType _toExternalType(DartType type) {
    if (type is InterfaceType && type.classNode == _util.wasmArrayClass) {
      return InterfaceType(_util.wasmArrayRefClass, type.declaredNullability);
    }
    return type;
  }
}
