// Copyright (c) 2017, 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:meta/meta.dart';

import '../base.dart';
import '../emitter.dart';
import '../visitors.dart';
import 'code.dart';
import 'method.dart';
import 'reference.dart';
import 'type_function.dart';

part 'expression/binary.dart';
part 'expression/closure.dart';
part 'expression/code.dart';
part 'expression/invoke.dart';
part 'expression/literal.dart';
part 'expression/parenthesized.dart';

/// Represents a [code] block that wraps an [Expression].

/// Represents a Dart expression.
///
/// See various concrete implementations for details.
abstract class Expression implements Spec {
  const Expression();

  /// An empty expression.
  static const _empty = CodeExpression(Code(''));

  /// Whether this expression implies a const context for sub expressions.
  ///
  /// Collection literals that are const imply const for all values.
  /// Assignment to a const variable implies a const value.
  /// Invoking a const constructor implies const for all arguments.
  ///
  /// The implied const context is used to omit redundant `const` keywords.
  /// A value of `false` does not imply that the expression cannot be used in a
  /// const context.
  bool get isConst => false;

  @override
  R accept<R>(covariant ExpressionVisitor<R> visitor, [R? context]);

  /// The expression as a valid [Code] block.
  ///
  /// Also see [statement].
  Code get code => ToCodeExpression(this);

  /// The expression as a valid [Code] block with a trailing `;`.
  Code get statement => ToCodeExpression(this, true);

  /// Returns the result of `this` `&&` [other].
  Expression and(Expression other) =>
      BinaryExpression._(expression, other, '&&');

  /// Returns the result of `this` `||` [other].
  Expression or(Expression other) =>
      BinaryExpression._(expression, other, '||');

  /// Returns the result of `!this`.
  Expression negate() =>
      BinaryExpression._(_empty, expression, '!', addSpace: false);

  /// Returns the result of `this` `as` [other].
  Expression asA(Expression other) =>
      ParenthesizedExpression._(BinaryExpression._(expression, other, 'as'));

  /// Returns accessing the index operator (`[]`) on `this`.
  Expression index(Expression index) => BinaryExpression._(
    expression,
    CodeExpression(Block.of([const Code('['), index.code, const Code(']')])),
    '',
  );

  /// Returns the result of `this` `is` [other].
  Expression isA(Expression other) =>
      BinaryExpression._(expression, other, 'is');

  /// Returns the result of `this` `is!` [other].
  Expression isNotA(Expression other) =>
      BinaryExpression._(expression, other, 'is!');

  /// Returns the result of `this` `==` [other].
  Expression equalTo(Expression other) =>
      BinaryExpression._(expression, other, '==');

  /// Returns the result of `this` `!=` [other].
  Expression notEqualTo(Expression other) =>
      BinaryExpression._(expression, other, '!=');

  /// Returns the result of `this` `>` [other].
  Expression greaterThan(Expression other) =>
      BinaryExpression._(expression, other, '>');

  /// Returns the result of `this` `<` [other].
  Expression lessThan(Expression other) =>
      BinaryExpression._(expression, other, '<');

  /// Returns the result of `this` `>=` [other].
  Expression greaterOrEqualTo(Expression other) =>
      BinaryExpression._(expression, other, '>=');

  /// Returns the result of `this` `<=` [other].
  Expression lessOrEqualTo(Expression other) =>
      BinaryExpression._(expression, other, '<=');

  /// Returns the result of `this` `+` [other].
  Expression operatorAdd(Expression other) =>
      BinaryExpression._(expression, other, '+');

  /// Returns the result of `this` `-` [other].
  Expression operatorSubtract(Expression other) =>
      BinaryExpression._(expression, other, '-');

  @Deprecated('Use `operatorSubtract` instead')
  Expression operatorSubstract(Expression other) => operatorSubtract(other);

  /// Returns the result of `this` `/` [other].
  Expression operatorDivide(Expression other) =>
      BinaryExpression._(expression, other, '/');

  /// Returns the result of `this` `*` [other].
  Expression operatorMultiply(Expression other) =>
      BinaryExpression._(expression, other, '*');

  /// Returns the result of `this` `%` [other].
  Expression operatorEuclideanModulo(Expression other) =>
      BinaryExpression._(expression, other, '%');

  /// Returns the result of `this` `~/` [other].
  Expression operatorIntDivide(Expression other) =>
      BinaryExpression._(expression, other, '~/');

  Expression conditional(Expression whenTrue, Expression whenFalse) =>
      BinaryExpression._(
        expression,
        BinaryExpression._(whenTrue, whenFalse, ':'),
        '?',
      );

  /// This expression preceded by `await`.
  Expression get awaited => BinaryExpression._(_empty, this, 'await');

  /// Returns the result of `++this`.
  Expression operatorUnaryPrefixIncrement() =>
      BinaryExpression._(_empty, expression, '++', addSpace: false);

  /// Return the result of `this++`.
  Expression operatorUnaryPostfixIncrement() =>
      BinaryExpression._(expression, _empty, '++', addSpace: false);

  /// Returns the result of `-this`.
  Expression operatorUnaryMinus() =>
      BinaryExpression._(_empty, expression, '-', addSpace: false);

  /// Returns the result of `--this`.
  Expression operatorUnaryPrefixDecrement() =>
      BinaryExpression._(_empty, expression, '--', addSpace: false);

  /// Return the result of `this--`.
  Expression operatorUnaryPostfixDecrement() =>
      BinaryExpression._(expression, _empty, '--', addSpace: false);

  /// Returns the result of `this` `&` [other].
  Expression operatorBitwiseAnd(Expression other) =>
      BinaryExpression._(expression, other, '&');

  /// Returns the result of `this` `|` [other].
  Expression operatorBitwiseOr(Expression other) =>
      BinaryExpression._(expression, other, '|');

  /// Returns the result of `this` `^` [other].
  Expression operatorBitwiseXor(Expression other) =>
      BinaryExpression._(expression, other, '^');

  /// Returns the result of `~this`.
  Expression operatorUnaryBitwiseComplement() =>
      BinaryExpression._(_empty, expression, '~', addSpace: false);

  /// Returns the result of `this` `<<` [other].
  Expression operatorShiftLeft(Expression other) =>
      BinaryExpression._(expression, other, '<<');

  /// Returns the result of `this` `>>` [other].
  Expression operatorShiftRight(Expression other) =>
      BinaryExpression._(expression, other, '>>');

  /// Returns the result of `this` `>>>` [other].
  Expression operatorShiftRightUnsigned(Expression other) =>
      BinaryExpression._(expression, other, '>>>');

  /// Return `{this} = {other}`.
  Expression assign(Expression other) =>
      BinaryExpression._(this, other, '=', isConst: isConst);

  /// Return `this` += [other].
  Expression addAssign(Expression other) =>
      BinaryExpression._(this, other, '+=');

  /// Return `this` -= [other].
  Expression subtractAssign(Expression other) =>
      BinaryExpression._(this, other, '-=');

  /// Return `this` *= [other].
  Expression multiplyAssign(Expression other) =>
      BinaryExpression._(this, other, '*=');

  /// Return `this` /= [other].
  Expression divideAssign(Expression other) =>
      BinaryExpression._(this, other, '/=');

  /// Return `this` ~/= [other].
  Expression intDivideAssign(Expression other) =>
      BinaryExpression._(this, other, '~/=');

  /// Return `this` %= [other].
  Expression euclideanModuloAssign(Expression other) =>
      BinaryExpression._(this, other, '%=');

  /// Return `this` <<= [other].
  Expression shiftLeftAssign(Expression other) =>
      BinaryExpression._(this, other, '<<=');

  /// Return `this` >>= [other].
  Expression shiftRightAssign(Expression other) =>
      BinaryExpression._(this, other, '>>=');

  /// Return `this` >>>= [other].
  Expression shiftRightUnsignedAssign(Expression other) =>
      BinaryExpression._(this, other, '>>>=');

  /// Return `this` &= [other].
  Expression bitwiseAndAssign(Expression other) =>
      BinaryExpression._(this, other, '&=');

  /// Return `this` ^= [other].
  Expression bitwiseXorAssign(Expression other) =>
      BinaryExpression._(this, other, '^=');

  /// Return `this` |= [other].
  Expression bitwiseOrAssign(Expression other) =>
      BinaryExpression._(this, other, '|=');

  /// Return `{this} ?? {other}`.
  Expression ifNullThen(Expression other) =>
      BinaryExpression._(this, other, '??');

  /// Return `{this} ??= {other}`.
  Expression assignNullAware(Expression other) =>
      BinaryExpression._(this, other, '??=');

  /// Return `var {name} = {this}`.
  @Deprecated('Use `declareVar(name).assign(expression)`')
  Expression assignVar(String name, [Reference? type]) => BinaryExpression._(
    type == null
        ? LiteralExpression._('var $name')
        : BinaryExpression._(type.expression, LiteralExpression._(name), ''),
    this,
    '=',
  );

  /// Return `final {name} = {this}`.
  @Deprecated('Use `declareFinal(name).assign(expression)`')
  Expression assignFinal(String name, [Reference? type]) => BinaryExpression._(
    type == null
        ? const LiteralExpression._('final')
        : BinaryExpression._(
          const LiteralExpression._('final'),
          type.expression,
          '',
        ),
    this,
    '$name =',
  );

  /// Return `const {name} = {this}`.
  @Deprecated('Use `declareConst(name).assign(expression)`')
  Expression assignConst(String name, [Reference? type]) => BinaryExpression._(
    type == null
        ? const LiteralExpression._('const')
        : BinaryExpression._(
          const LiteralExpression._('const'),
          type.expression,
          '',
        ),
    this,
    '$name =',
    isConst: true,
  );

  /// Call this expression as a method.
  Expression call(
    Iterable<Expression> positionalArguments, [
    Map<String, Expression> namedArguments = const {},
    List<Reference> typeArguments = const [],
  ]) => InvokeExpression._(
    this,
    positionalArguments.toList(),
    namedArguments,
    typeArguments,
  );

  /// Returns an expression accessing `.<name>` on this expression.
  Expression property(String name) =>
      BinaryExpression._(this, LiteralExpression._(name), '.', addSpace: false);

  /// Returns an expression accessing `..<name>` on this expression.
  Expression cascade(String name) => BinaryExpression._(
    this,
    LiteralExpression._(name),
    '..',
    addSpace: false,
  );

  /// Returns an expression accessing `?.<name>` on this expression.
  Expression nullSafeProperty(String name) => BinaryExpression._(
    this,
    LiteralExpression._(name),
    '?.',
    addSpace: false,
  );

  /// Applies the null check operator on this expression, returning `this` `!`.
  ///
  /// Please note that this is only valid when emitting code with the null
  /// safety syntax enabled.
  Expression get nullChecked => BinaryExpression._(
    this,
    const LiteralExpression._('!'),
    '',
    addSpace: false,
  );

  /// This expression preceded by `return`.
  Expression get returned =>
      BinaryExpression._(const LiteralExpression._('return'), this, '');

  /// This expression preceded by the spread operator `...`.
  Expression get spread => BinaryExpression._(
    const LiteralExpression._('...'),
    this,
    '',
    addSpace: false,
  );

  /// This expression preceded by the null safe spread operator `?...`.
  Expression get nullSafeSpread => BinaryExpression._(
    const LiteralExpression._('...?'),
    this,
    '',
    addSpace: false,
  );

  /// This expression preceded by `throw`.
  Expression get thrown =>
      BinaryExpression._(const LiteralExpression._('throw'), this, '');

  /// May be overridden to support other types implementing [Expression].
  @visibleForOverriding
  Expression get expression => this;

  /// Returns this expression wrapped in parenthesis.
  ParenthesizedExpression get parenthesized => ParenthesizedExpression._(this);
}

/// Declare a const variable named [variableName].
///
/// Returns `const {variableName}`, or `const {type} {variableName}`.
Expression declareConst(String variableName, {Reference? type}) =>
    BinaryExpression._(
      const LiteralExpression._('const'),
      type == null
          ? LiteralExpression._(variableName)
          : _typedVar(variableName, type),
      '',
      isConst: true,
    );

/// Declare a final variable named [variableName].
///
/// Returns `final {variableName}`, or `final {type} {variableName}`.
/// If [late] is true the declaration is prefixed with `late`.
Expression declareFinal(
  String variableName, {
  Reference? type,
  bool late = false,
}) => _late(
  late,
  type == null
      ? LiteralExpression._('final $variableName')
      : BinaryExpression._(
        const LiteralExpression._('final'),
        _typedVar(variableName, type),
        '',
      ),
);

/// Declare a variable named [variableName].
///
/// Returns `var {variableName}`, or `{type} {variableName}`.
/// If [late] is true the declaration is prefixed with `late`.
Expression declareVar(
  String variableName, {
  Reference? type,
  bool late = false,
}) => _late(
  late,
  type == null
      ? LiteralExpression._('var $variableName')
      : _typedVar(variableName, type),
);

Expression _typedVar(String variableName, Reference type) =>
    BinaryExpression._(type.expression, LiteralExpression._(variableName), '');

Expression _late(bool late, Expression expression) =>
    late
        ? BinaryExpression._(const LiteralExpression._('late'), expression, '')
        : expression;

/// Creates `typedef {name} =`.
Code createTypeDef(String name, FunctionType type) =>
    BinaryExpression._(
      LiteralExpression._('typedef $name'),
      type.expression,
      '=',
    ).statement;

class ToCodeExpression implements Code {
  final Expression code;

  /// Whether this code should be considered a _statement_.
  final bool isStatement;

  @visibleForTesting
  const ToCodeExpression(this.code, [this.isStatement = false]);

  @override
  R accept<R>(CodeVisitor<R> visitor, [R? context]) =>
      (visitor as ExpressionVisitor<R>).visitToCodeExpression(this, context);

  @override
  String toString() => code.toString();
}

/// Knowledge of different types of expressions in Dart.
///
/// **INTERNAL ONLY**.
abstract class ExpressionVisitor<T> implements SpecVisitor<T> {
  T visitToCodeExpression(ToCodeExpression code, [T? context]);
  T visitBinaryExpression(BinaryExpression expression, [T? context]);
  T visitClosureExpression(ClosureExpression expression, [T? context]);
  T visitCodeExpression(CodeExpression expression, [T? context]);
  T visitInvokeExpression(InvokeExpression expression, [T? context]);
  T visitLiteralExpression(LiteralExpression expression, [T? context]);
  T visitLiteralListExpression(LiteralListExpression expression, [T? context]);
  T visitLiteralSetExpression(LiteralSetExpression expression, [T? context]);
  T visitLiteralMapExpression(LiteralMapExpression expression, [T? context]);
  T visitLiteralRecordExpression(
    LiteralRecordExpression expression, [
    T? context,
  ]);
  T visitParenthesizedExpression(
    ParenthesizedExpression expression, [
    T? context,
  ]);
}

/// Knowledge of how to write valid Dart code from [ExpressionVisitor].
///
/// **INTERNAL ONLY**.
abstract mixin class ExpressionEmitter
    implements ExpressionVisitor<StringSink> {
  @override
  StringSink visitToCodeExpression(
    ToCodeExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    expression.code.accept(this, output);
    if (expression.isStatement) {
      output.write(';');
    }
    return output;
  }

  @override
  StringSink visitBinaryExpression(
    BinaryExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    expression.left.accept(this, output);
    if (expression.addSpace) {
      output.write(' ');
    }
    output.write(expression.operator);
    if (expression.addSpace) {
      output.write(' ');
    }
    startConstCode(expression.isConst, () {
      expression.right.accept(this, output);
    });
    return output;
  }

  @override
  StringSink visitClosureExpression(
    ClosureExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    return expression.method.accept(this, output);
  }

  @override
  StringSink visitCodeExpression(
    CodeExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    final visitor = this as CodeVisitor<StringSink>;
    return expression.code.accept(visitor, output);
  }

  @override
  StringSink visitInvokeExpression(
    InvokeExpression expression, [
    StringSink? output,
  ]) {
    final out = output ??= StringBuffer();
    return _writeConstExpression(out, expression.isConst, () {
      expression.target.accept(this, out);
      if (expression.name case final name? when name.isNotEmpty) {
        out
          ..write('.')
          ..write(name);
      }
      if (expression.typeArguments.isNotEmpty) {
        out.write('<');
        visitAll<Reference>(expression.typeArguments, out, (type) {
          type.accept(this, out);
        });
        out.write('>');
      }
      out.write('(');
      visitAll<Spec>(expression.positionalArguments, out, (spec) {
        spec.accept(this, out);
      });
      if (expression.positionalArguments.isNotEmpty &&
          expression.namedArguments.isNotEmpty) {
        out.write(', ');
      }
      visitAll<String>(expression.namedArguments.keys, out, (name) {
        out
          ..write(name)
          ..write(': ');
        expression.namedArguments[name]!.accept(this, out);
      });
      final argumentCount =
          expression.positionalArguments.length +
          expression.namedArguments.length;
      if (argumentCount > 1) {
        out.write(', ');
      }
      return out..write(')');
    });
  }

  @override
  StringSink visitLiteralExpression(
    LiteralExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    return output..write(expression.literal);
  }

  void _acceptLiteral(Object? literalOrSpec, StringSink output) {
    if (literalOrSpec is Spec) {
      literalOrSpec.accept(this, output);
      return;
    }
    literal(literalOrSpec).accept(this, output);
  }

  bool _withInConstExpression = false;

  @override
  StringSink visitLiteralListExpression(
    LiteralListExpression expression, [
    StringSink? output,
  ]) {
    final out = output ??= StringBuffer();

    return _writeConstExpression(output, expression.isConst, () {
      if (expression.type != null) {
        out.write('<');
        expression.type!.accept(this, output);
        out.write('>');
      }
      out.write('[');
      visitAll<Object?>(expression.values, out, (value) {
        _acceptLiteral(value, out);
      });
      if (expression.values.length > 1) {
        out.write(', ');
      }
      return out..write(']');
    });
  }

  @override
  StringSink visitLiteralSetExpression(
    LiteralSetExpression expression, [
    StringSink? output,
  ]) {
    final out = output ??= StringBuffer();

    return _writeConstExpression(output, expression.isConst, () {
      if (expression.type != null) {
        out.write('<');
        expression.type!.accept(this, output);
        out.write('>');
      }
      out.write('{');
      visitAll<Object?>(expression.values, out, (value) {
        _acceptLiteral(value, out);
      });
      if (expression.values.length > 1) {
        out.write(', ');
      }
      return out..write('}');
    });
  }

  @override
  StringSink visitLiteralMapExpression(
    LiteralMapExpression expression, [
    StringSink? output,
  ]) {
    final out = output ??= StringBuffer();
    return _writeConstExpression(out, expression.isConst, () {
      if (expression.keyType != null) {
        out.write('<');
        expression.keyType!.accept(this, out);
        out.write(', ');
        if (expression.valueType == null) {
          const Reference('dynamic', 'dart:core').accept(this, out);
        } else {
          expression.valueType!.accept(this, out);
        }
        out.write('>');
      }
      out.write('{');
      visitAll<Object?>(expression.values.keys, out, (key) {
        final value = expression.values[key];
        _acceptLiteral(key, out);
        if (key is! LiteralSpreadExpression) {
          out.write(': ');
        }
        _acceptLiteral(value, out);
      });
      if (expression.values.length > 1) {
        out.write(', ');
      }
      return out..write('}');
    });
  }

  @override
  StringSink visitLiteralRecordExpression(
    LiteralRecordExpression expression, [
    StringSink? output,
  ]) {
    final out = output ??= StringBuffer();
    return _writeConstExpression(out, expression.isConst, () {
      out.write('(');
      visitAll<Object?>(expression.positionalFieldValues, out, (value) {
        _acceptLiteral(value, out);
      });
      if (expression.namedFieldValues.isNotEmpty) {
        if (expression.positionalFieldValues.isNotEmpty) {
          out.write(', ');
        }
      } else if (expression.positionalFieldValues.length == 1) {
        out.write(',');
      }
      visitAll<MapEntry<String, Object?>>(
        expression.namedFieldValues.entries,
        out,
        (entry) {
          out.write('${entry.key}: ');
          _acceptLiteral(entry.value, out);
        },
      );
      return out..write(')');
    });
  }

  @override
  StringSink visitParenthesizedExpression(
    ParenthesizedExpression expression, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    output.write('(');
    expression.inner.accept(this, output);
    output.write(')');
    return output;
  }

  /// Executes [visit] within a context which may alter the output if [isConst]
  /// is `true`.
  ///
  /// This allows constant expressions to omit the `const` keyword if they
  /// are already within a constant expression.
  void startConstCode(bool isConst, Null Function() visit) {
    final previousConstContext = _withInConstExpression;
    if (isConst) {
      _withInConstExpression = true;
    }

    visit();
    _withInConstExpression = previousConstContext;
  }

  /// Similar to [startConstCode], but handles writing `"const "` if [isConst]
  /// is `true` and the invocation is not nested under other invocations where
  /// [isConst] is true.
  StringSink _writeConstExpression(
    StringSink sink,
    bool isConst,
    StringSink Function() visitExpression,
  ) {
    final previousConstContext = _withInConstExpression;
    if (isConst) {
      if (!_withInConstExpression) {
        sink.write('const ');
      }
      _withInConstExpression = true;
    }

    final returnedSink = visitExpression();
    assert(identical(returnedSink, sink));
    _withInConstExpression = previousConstContext;
    return sink;
  }
}
