// 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.

/// Efficient JavaScript code builder.
///
/// Used to create wrapper expressions and functions for expression evaluation.
class JsBuilder {
  var _indent = 0;
  final _buffer = StringBuffer();

  String? _built;
  String build() => _built ??= _buffer.toString();

  JsBuilder();

  void write(String item) {
    _buffer.write(item);
  }

  void writeLine(String item) {
    _buffer.writeln(item);
  }

  void writeAll(Iterable<String> items, [String separator = '']) {
    _buffer.writeAll(items, separator);
  }

  void _writeIndent() {
    writeAll([for (var i = 0; i < _indent * 2; i++) ' '], '');
  }

  void writeWithIndent(String item) {
    _writeIndent();
    write(item);
  }

  void writeLineWithIndent(String line) {
    _writeIndent();
    writeLine(line);
  }

  void writeMultiLineExpression(Iterable<String> lines) {
    var i = 0;
    for (var line in lines) {
      if (i == 0) {
        writeLine(line);
      } else if (i < lines.length - 1) {
        writeLineWithIndent(line);
      } else {
        writeWithIndent(line);
      }
      i++;
    }
  }

  void increaseIndent() {
    _indent++;
  }

  void decreaseIndent() {
    if (_indent != 0) _indent--;
  }

  /// Call the expression built by [build] with [args].
  ///
  /// $function($args);
  void writeCallExpression(
    Iterable<String> args,
    void Function() build,
  ) {
    build();
    write('(');
    writeAll(args, ', ');
    write(')');
  }

  /// Wrap the expression built by [build] in try/catch block.
  ///
  /// try {
  ///   $expression;
  /// } catch (error) {
  ///   error.name + ": " + error.message;
  /// };
  void writeTryCatchExpression(void Function() build) {
    writeLineWithIndent('try {');

    increaseIndent();
    writeWithIndent('');
    build();
    writeLine('');
    decreaseIndent();

    writeLineWithIndent('} catch (error) {');
    writeLineWithIndent('  error.name + ": " + error.message;');
    writeWithIndent('}');
  }

  ///  Wrap the statement built by [build] in try/catch block.
  ///
  /// try {
  ///   $statement
  /// } catch (error) {
  ///   return error.name + ": " + error.message;
  /// };
  void writeTryCatchStatement(void Function() build) {
    writeLineWithIndent('try {');

    increaseIndent();
    build();
    writeLine('');
    decreaseIndent();

    writeLineWithIndent('} catch (error) {');
    writeLineWithIndent('  return error.name + ": " + error.message;');
    writeWithIndent('}');
  }

  /// Return the expression built by [build].
  ///
  /// return $expression;
  void writeReturnStatement(void Function() build) {
    writeWithIndent('return ');
    build();
    write(';');
  }

  /// Define a function with [params] and body built by [build].
  ///
  /// function($args) {
  ///   $body
  /// };
  void writeFunctionDefinition(
    Iterable<String> params,
    void Function() build,
  ) {
    write('function (');
    writeAll(params, ', ');
    writeLine(') {');

    increaseIndent();
    build();
    writeLine('');
    decreaseIndent();

    writeWithIndent('}');
  }

  /// Bind the function built by [build] to [to].
  ///
  /// $function.bind($to)
  void writeBindExpression(
    String to,
    void Function() build,
  ) {
    build();
    write('.bind(');
    write(to);
    write(')');
  }

  /// Create a wrapper expression to evaluate the [body].
  ///
  /// Can be used in `Debugger.evaluateOnCallFrame` Chrome API.
  ///
  /// try {
  ///   $expression;
  /// } catch (error) {
  ///   error.name + ": " + error.message;
  /// }
  static String createEvalExpression(Iterable<String> body) =>
      (JsBuilder().._writeEvalExpression(body)).build();

  void _writeEvalExpression(Iterable<String> body) {
    writeTryCatchExpression(() {
      writeMultiLineExpression(body);
      write(';');
    });
  }

  /// Create a wrapper function with [params] that calls a static [function].
  ///
  /// Can be used in `Runtime.callFunctionOn` Chrome API.
  ///
  /// function ($params) {
  ///   try {
  ///     return $function($params);
  ///   } catch (error) {
  ///     return error.name + ": " + error.message;
  ///   }
  /// }
  static String createEvalStaticFunction(
    Iterable<String> function,
    Iterable<String> params,
  ) =>
      (JsBuilder().._writeEvalStaticFunction(function, params)).build();

  void _writeEvalStaticFunction(
    Iterable<String> function,
    Iterable<String> params,
  ) {
    writeFunctionDefinition(
      params,
      () => writeTryCatchStatement(
        () => writeReturnStatement(
          () => writeCallExpression(
            params,
            () {
              writeMultiLineExpression(function);
            },
          ),
        ),
      ),
    );
  }

  /// Create a wrapper function with [params] that calls a bound [function].
  ///
  /// Can be used in `Runtime.callFunctionOn` Chrome API.
  /// function ($params, __t$this) {
  ///   try {
  ///     return function ($params) {
  ///       return $function($params);
  ///     }.bind(__t$this)($params);
  ///   } catch (error) {
  ///     return error.name + ": " + error.message;
  ///   }
  /// }
  static String createEvalBoundFunction(
    Iterable<String> function,
    Iterable<String> params,
  ) =>
      (JsBuilder().._writeEvalBoundFunction(function, params)).build();

  void _writeEvalBoundFunction(
    Iterable<String> function,
    Iterable<String> params,
  ) {
    final original = 'this';
    final substitute = '__t\$this';

    final args = params.where((e) => e != original);
    final substitutedParams = [
      ...params.where((e) => e != original),
      substitute,
    ];

    writeFunctionDefinition(
      substitutedParams,
      () => writeTryCatchStatement(
        () => writeReturnStatement(
          () => writeCallExpression(
            args,
            () => writeBindExpression(
              substitute,
              () => writeFunctionDefinition(
                args,
                () => writeReturnStatement(
                  () => writeCallExpression(
                    args,
                    () {
                      writeMultiLineExpression(function);
                    },
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
