// 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;
  }
}
