// 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 '../ast.dart';
import 'text_util.dart';

/// AST printer strategy used by default in `Node.toString`.
///
/// Don't use this for testing. Instead use [astTextStrategyForTesting] or
/// make an explicit strategy for the test to avoid test dependency on the
/// `Node.toString` implementation.
const AstTextStrategy defaultAstTextStrategy = const AstTextStrategy();

/// Strategy used for printing AST nodes.
///
/// This is used to avoid dependency on the `Node.toString` implementations
/// in testing.
const AstTextStrategy astTextStrategyForTesting = const AstTextStrategy(
    includeLibraryNamesInMembers: true,
    includeLibraryNamesInTypes: true,
    includeAuxiliaryProperties: false,
    useMultiline: false);

class AstTextStrategy {
  /// If `true`, references to classes and typedefs in types are prefixed by the
  /// name of their enclosing library.
  final bool includeLibraryNamesInTypes;

  /// If `true`, references to members, classes and typedefs are prefixed by the
  /// name of their enclosing library.
  final bool includeLibraryNamesInMembers;

  /// If `true`, auxiliary node properties are on include in the textual
  /// representation.
  final bool includeAuxiliaryProperties;

  /// If `true`, newlines are used to separate statements.
  final bool useMultiline;

  /// If [useMultiline] is `true`, [indentation] is used for indentation.
  final String indentation;

  /// If non-null, a maximum of [maxStatementDepth] nested statements are
  /// printed. If exceeded, '...' is printed instead.
  final int? maxStatementDepth;

  /// If non-null, a maximum of [maxStatementsLength] statements are printed
  /// within the same block.
  final int? maxStatementsLength;

  /// If non-null, a maximum of [maxExpressionDepth] nested expression are
  /// printed. If exceeded, '...' is printed instead.
  final int? maxExpressionDepth;

  /// If non-null, a maximum of [maxExpressionsLength] expression are printed
  /// within the same list of expressions, for instance in list/set literals.
  /// If exceeded, '...' is printed instead.
  final int? maxExpressionsLength;

  const AstTextStrategy(
      {this.includeLibraryNamesInTypes: false,
      this.includeLibraryNamesInMembers: false,
      this.includeAuxiliaryProperties: false,
      this.useMultiline: true,
      this.indentation: '  ',
      this.maxStatementDepth: null,
      this.maxStatementsLength: null,
      this.maxExpressionDepth: null,
      this.maxExpressionsLength: null});
}

class AstPrinter {
  final AstTextStrategy _strategy;
  final StringBuffer _sb = new StringBuffer();
  int _statementLevel = 0;
  int _expressionLevel = 0;
  int _indentationLevel = 0;
  late final Map<LabeledStatement, String> _labelNames = {};
  late final Map<VariableDeclaration, String> _variableNames = {};

  AstPrinter(this._strategy);

  bool get includeAuxiliaryProperties => _strategy.includeAuxiliaryProperties;

  void incIndentation() {
    _indentationLevel++;
  }

  void decIndentation() {
    _indentationLevel--;
  }

  void write(String value) {
    _sb.write(value);
  }

  void writeClassName(Reference? reference, {bool forType: false}) {
    _sb.write(qualifiedClassNameToStringByReference(reference,
        includeLibraryName: forType
            ? _strategy.includeLibraryNamesInTypes
            : _strategy.includeLibraryNamesInMembers));
  }

  void writeTypedefName(Reference? reference) {
    _sb.write(qualifiedTypedefNameToStringByReference(reference,
        includeLibraryName: _strategy.includeLibraryNamesInTypes));
  }

  void writeExtensionName(Reference? reference) {
    _sb.write(qualifiedExtensionNameToStringByReference(reference,
        includeLibraryName: _strategy.includeLibraryNamesInMembers));
  }

  void writeMemberName(Reference? reference) {
    _sb.write(qualifiedMemberNameToStringByReference(reference,
        includeLibraryName: _strategy.includeLibraryNamesInMembers));
  }

  void writeInterfaceMemberName(Reference? reference, Name? name) {
    if (name != null && (reference == null || reference.node == null)) {
      writeName(name);
    } else {
      write('{');
      _sb.write(qualifiedMemberNameToStringByReference(reference,
          includeLibraryName: _strategy.includeLibraryNamesInMembers));
      write('}');
    }
  }

  void writeName(Name? name) {
    _sb.write(nameToString(name,
        includeLibraryName: _strategy.includeLibraryNamesInMembers));
  }

  void writeNamedType(NamedType node) {
    node.toTextInternal(this);
  }

  void writeTypeParameterName(TypeParameter parameter) {
    _sb.write(qualifiedTypeParameterNameToString(parameter,
        includeLibraryName: _strategy.includeLibraryNamesInTypes));
  }

  void newLine() {
    if (_strategy.useMultiline) {
      _sb.writeln();
      _sb.write(_strategy.indentation * _indentationLevel);
    } else {
      _sb.write(' ');
    }
  }

  String getLabelName(LabeledStatement node) {
    return _labelNames[node] ??= 'label${_labelNames.length}';
  }

  String getVariableName(VariableDeclaration node) {
    String? name = node.name;
    if (name != null) {
      return name;
    }
    return _variableNames[node] ??= '#${_variableNames.length}';
  }

  String getSwitchCaseName(SwitchCase node) {
    if (node.isDefault) {
      return '"default:"';
    } else {
      return '"case ${node.expressions.first.toText(_strategy)}:"';
    }
  }

  void writeStatement(Statement node) {
    int oldStatementLevel = _statementLevel;
    _statementLevel++;
    if (_strategy.maxStatementDepth != null &&
        _statementLevel > _strategy.maxStatementDepth!) {
      _sb.write('...');
    } else {
      node.toTextInternal(this);
    }
    _statementLevel = oldStatementLevel;
  }

  void writeExpression(Expression node, {int? minimumPrecedence}) {
    int oldExpressionLevel = _expressionLevel;
    _expressionLevel++;
    if (_strategy.maxExpressionDepth != null &&
        _expressionLevel > _strategy.maxExpressionDepth!) {
      _sb.write('...');
    } else {
      bool needsParentheses =
          minimumPrecedence != null && node.precedence < minimumPrecedence;
      if (needsParentheses) {
        _sb.write('(');
      }
      node.toTextInternal(this);
      if (needsParentheses) {
        _sb.write(')');
      }
    }
    _expressionLevel = oldExpressionLevel;
  }

  void writeNamedExpression(NamedExpression node) {
    node.toTextInternal(this);
  }

  void writeCatch(Catch node) {
    node.toTextInternal(this);
  }

  void writeSwitchCase(SwitchCase node) {
    node.toTextInternal(this);
  }

  void writeType(DartType node) {
    node.toTextInternal(this);
  }

  void writeConstant(Constant node) {
    node.toTextInternal(this);
  }

  void writeMapEntry(MapLiteralEntry node) {
    node.toTextInternal(this);
  }

  /// Writes [types] to the printer buffer separated by ', '.
  void writeTypes(List<DartType> types) {
    for (int index = 0; index < types.length; index++) {
      if (index > 0) {
        _sb.write(', ');
      }
      writeType(types[index]);
    }
  }

  /// If [types] is non-empty, writes [types] to the printer buffer delimited by
  /// '<' and '>', and separated by ', '.
  void writeTypeArguments(List<DartType> types) {
    if (types.isNotEmpty) {
      _sb.write('<');
      writeTypes(types);
      _sb.write('>');
    }
  }

  /// If [typeParameters] is non-empty, writes [typeParameters] to the printer
  /// buffer delimited by '<' and '>', and separated by ', '.
  ///
  /// The bound of a type parameter is included, as 'T extends Bound', if the
  /// bound is neither `Object?` nor `Object*`.
  void writeTypeParameters(List<TypeParameter> typeParameters) {
    if (typeParameters.isNotEmpty) {
      _sb.write("<");
      String comma = "";
      for (TypeParameter typeParameter in typeParameters) {
        _sb.write(comma);
        _sb.write(typeParameter.name);
        DartType bound = typeParameter.bound;

        bool isTopObject(DartType type) {
          if (type is InterfaceType &&
              type.className.node != null &&
              type.classNode.name == 'Object') {
            Uri uri = type.classNode.enclosingLibrary.importUri;
            return uri.scheme == 'dart' &&
                uri.path == 'core' &&
                (type.nullability == Nullability.legacy ||
                    type.nullability == Nullability.nullable);
          }
          return false;
        }

        if (!isTopObject(bound) || isTopObject(typeParameter.defaultType)) {
          // Include explicit bounds only.
          _sb.write(' extends ');
          writeType(bound);
        }
        comma = ", ";
      }
      _sb.write(">");
    }
  }

  /// Writes [expressions] to the printer buffer separated by ', '.
  void writeExpressions(List<Expression> expressions) {
    if (expressions.isNotEmpty &&
        _strategy.maxExpressionDepth != null &&
        _expressionLevel + 1 > _strategy.maxExpressionDepth!) {
      // The maximum expression depth will be exceeded for all [expressions].
      // Print the list as one occurrence '...' instead one per expression.
      _sb.write('...');
    } else if (_strategy.maxExpressionsLength != null &&
        expressions.length > _strategy.maxExpressionsLength!) {
      _sb.write('...');
    } else {
      for (int index = 0; index < expressions.length; index++) {
        if (index > 0) {
          _sb.write(', ');
        }
        writeExpression(expressions[index]);
      }
    }
  }

  /// Writes [statements] to the printer buffer delimited by '{' and '}'.
  ///
  /// If using a multiline strategy, the statements printed on separate lines
  /// that are indented one level.
  void writeBlock(List<Statement> statements) {
    if (statements.isEmpty) {
      write('{}');
    } else {
      write('{');
      incIndentation();
      writeStatements(statements);
      decIndentation();
      newLine();
      write('}');
    }
  }

  /// Writes [statements] to the printer buffer.
  ///
  /// If using a multiline strategy, the statements printed on separate lines
  /// that are indented one level.
  void writeStatements(List<Statement> statements) {
    if (statements.isNotEmpty &&
        _strategy.maxStatementDepth != null &&
        _statementLevel + 1 > _strategy.maxStatementDepth!) {
      // The maximum statement depth will be exceeded for all [statements].
      // Print the list as one occurrence '...' instead one per statement.
      _sb.write(' ...');
    } else if (_strategy.maxStatementsLength != null &&
        statements.length > _strategy.maxStatementsLength!) {
      _sb.write(' ...');
    } else {
      for (Statement statement in statements) {
        newLine();
        writeStatement(statement);
      }
    }
  }

  /// Writes arguments [node] to the printer buffer.
  ///
  /// If [includeTypeArguments] is `true` type arguments in [node] are included.
  /// Otherwise only the positional and named arguments are included.
  void writeArguments(Arguments node, {bool includeTypeArguments: true}) {
    node.toTextInternal(this, includeTypeArguments: includeTypeArguments);
  }

  /// Writes the variable declaration [node] to the printer buffer.
  ///
  /// If [includeModifiersAndType] is `true`, the declaration is prefixed by
  /// the modifiers and declared type of the variable. Otherwise only the
  /// name and the initializer, if present, are included.
  ///
  /// If [isLate] and [type] are provided, these values are used instead of
  /// the corresponding properties on [node].
  void writeVariableDeclaration(VariableDeclaration node,
      {bool includeModifiersAndType: true,
      bool? isLate,
      DartType? type,
      bool includeInitializer: true}) {
    if (includeModifiersAndType) {
      if (node.isRequired) {
        _sb.write('required ');
      }
      if (isLate ?? node.isLate) {
        _sb.write('late ');
      }
      if (node.isFinal) {
        _sb.write('final ');
      }
      if (node.isConst) {
        _sb.write('const ');
      }
      writeType(type ?? node.type);
      _sb.write(' ');
    }
    _sb.write(getVariableName(node));
    if (includeInitializer && node.initializer != null && !node.isRequired) {
      _sb.write(' = ');
      writeExpression(node.initializer!);
    }
  }

  void writeFunctionNode(FunctionNode node, String name) {
    writeType(node.returnType);
    _sb.write(' ');
    _sb.write(name);
    if (node.typeParameters.isNotEmpty) {
      _sb.write('<');
      for (int index = 0; index < node.typeParameters.length; index++) {
        if (index > 0) {
          _sb.write(', ');
        }
        _sb.write(node.typeParameters[index].name);
        _sb.write(' extends ');
        writeType(node.typeParameters[index].bound);
      }
      _sb.write('>');
    }
    _sb.write('(');
    for (int index = 0; index < node.positionalParameters.length; index++) {
      if (index > 0) {
        _sb.write(', ');
      }
      if (index == node.requiredParameterCount) {
        _sb.write('[');
      }
      writeVariableDeclaration(node.positionalParameters[index]);
    }
    if (node.requiredParameterCount < node.positionalParameters.length) {
      _sb.write(']');
    }
    if (node.namedParameters.isNotEmpty) {
      if (node.positionalParameters.isNotEmpty) {
        _sb.write(', ');
      }
      _sb.write('{');
      for (int index = 0; index < node.namedParameters.length; index++) {
        if (index > 0) {
          _sb.write(', ');
        }
        writeVariableDeclaration(node.namedParameters[index]);
      }
      _sb.write('}');
    }
    _sb.write(')');
    Statement? body = node.body;
    // ignore: unnecessary_null_comparison
    if (body != null) {
      if (body is ReturnStatement) {
        _sb.write(' => ');
        writeExpression(body.expression!);
      } else {
        _sb.write(' ');
        writeStatement(body);
      }
    } else {
      _sb.write(';');
    }
  }

  void writeConstantMapEntry(ConstantMapEntry node) {
    node.toTextInternal(this);
  }

  /// Returns the text written to this printer.
  String getText() => _sb.toString();
}
