// 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`, only [Nullability.nullable] is shown on types.
  final bool showNullableOnly;

  /// If `true`, type parameter names qualified by the name of the declaring
  /// class or function.
  final bool useQualifiedTypeParameterNames;

  /// If `true`, type parameter names qualified also by local functions
  /// (if named).
  final bool useQualifiedTypeParameterNamesRecurseOnNamedLocalFunctions;

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

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

  const AstTextStrategy(
      {this.includeLibraryNamesInTypes = false,
      this.includeLibraryNamesInMembers = false,
      this.includeAuxiliaryProperties = false,
      this.showNullableOnly = false,
      this.useQualifiedTypeParameterNames = true,
      this.useQualifiedTypeParameterNamesRecurseOnNamedLocalFunctions = false,
      this.useMultiline = true,
      this.indentation = '  ',
      this.maxStatementDepth = 50,
      this.maxStatementsLength = null,
      this.maxExpressionDepth = 50,
      this.maxExpressionsLength = null,
      this.maxConstantDepth = 10});
}

class AstPrinter {
  final AstTextStrategy _strategy;
  final StringBuffer _sb = new StringBuffer();
  int _statementLevel = 0;
  int _expressionLevel = 0;
  int _constantLevel = 0;
  int _indentationLevel = 0;
  late final Map<LabeledStatement, String> _labelNames = {};
  late final Map<VariableDeclaration, String> _variableDeclarationNames = {};
  late final Map<Variable, 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 writeExtensionTypeDeclarationName(Reference? reference) {
    _sb.write(qualifiedExtensionTypeDeclarationNameToStringByReference(
        reference,
        includeLibraryName: _strategy.includeLibraryNamesInMembers));
  }

  void writeQualifiedCanonicalNameToString(CanonicalName canonicalName) {
    _sb.write(qualifiedCanonicalNameToString(canonicalName,
        includeLibraryName: _strategy.includeLibraryNamesInMembers,
        includeLibraryNamesInTypes: _strategy.includeLibraryNamesInTypes));
  }

  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 writeLibraryReference(Reference reference) {
    _sb.write(libraryReferenceToString(reference));
  }

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

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

  void writeTypeParameterName(TypeParameter parameter) {
    _sb.write(_strategy.useQualifiedTypeParameterNames
        ? qualifiedTypeParameterNameToString(parameter,
            includeLibraryName: _strategy.includeLibraryNamesInTypes,
            recurseOnLocalFunction: _strategy
                .useQualifiedTypeParameterNamesRecurseOnNamedLocalFunctions)
        : typeParameterNameToString(parameter));
  }

  void writeStructuralParameterName(StructuralParameter parameter) {
    _sb.write(_strategy.useQualifiedTypeParameterNames
        ? qualifiedStructuralParameterNameToString(parameter,
            includeLibraryName: _strategy.includeLibraryNamesInTypes)
        : structuralParameterNameToString(parameter));
  }

  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(Variable node) {
    switch (node) {
      case NamedParameter(parameterName: var name):
      case PositionalParameter(cosmeticName: var name?):
      case TypeVariable(cosmeticName: var name?):
      case LocalVariable(cosmeticName: var name?):
        return name;
      case ThisVariable():
        return 'this';
      case PositionalParameter(cosmeticName: null):
      case TypeVariable(cosmeticName: null):
      case LocalVariable(cosmeticName: null):
      case SyntheticVariable():
        return _variableNames[node] ??= '#${_variableNames.length}';
      case VariableDeclaration():
        String? name = node.name;
        if (name != null) {
          return name;
        }
        return _variableDeclarationNames[node] ??=
            '#${_variableDeclarationNames.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 writeNullability(Nullability nullability) {
    if (!_strategy.showNullableOnly || nullability == Nullability.nullable) {
      write(nullabilityToString(nullability));
    }
  }

  void writeConstant(Constant node) {
    int oldConstantLevel = _constantLevel;
    _constantLevel++;
    if (_strategy.maxConstantDepth != null &&
        _constantLevel > _strategy.maxConstantDepth!) {
      _sb.write('...');
    } else {
      node.toTextInternal(this);
    }
    _constantLevel = oldConstantLevel;
  }

  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.classReference.node != null &&
              type.classNode.name == 'Object') {
            Uri uri = type.classNode.enclosingLibrary.importUri;
            return uri.isScheme('dart') &&
                uri.path == 'core' &&
                type.nullability == Nullability.nullable;
          }
          return false;
        }

        if (!isTopObject(bound) || isTopObject(typeParameter.defaultType)) {
          // Include explicit bounds only.
          _sb.write(' extends ');
          writeType(bound);
        }
        comma = ", ";
      }
      _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 writeStructuralParameters(List<StructuralParameter> typeParameters) {
    if (typeParameters.isNotEmpty) {
      _sb.write("<");
      String comma = "";
      for (StructuralParameter typeParameter in typeParameters) {
        _sb.write(comma);
        _sb.write(typeParameter.name);
        DartType bound = typeParameter.bound;

        bool isTopObject(DartType type) {
          if (type is InterfaceType &&
              type.classReference.node != null &&
              type.classNode.name == 'Object') {
            Uri uri = type.classNode.enclosingLibrary.importUri;
            return uri.isScheme('dart') &&
                uri.path == 'core' &&
                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 [VariableInitialization] [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 writeVariableInitialization(VariableInitialization 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.variable));
    if (includeInitializer && node.initializer != null && !node.isRequired) {
      _sb.write(' = ');
      writeExpression(node.initializer!);
    }
  }

  /// 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 writeExpressionVariable(ExpressionVariable node,
      {bool includeModifiersAndType = true, bool? isLate, DartType? type}) {
    if (includeModifiersAndType) {
      if (node is FunctionParameter && node.isRequired) {
        _sb.write('required ');
      }
      if (isLate ?? (node is! FunctionParameter && node.isLate)) {
        _sb.write('late ');
      }
      if (node is! FunctionParameter && node.isFinal) {
        _sb.write('final ');
      }
      if (node is! FunctionParameter && node.isConst) {
        _sb.write('const ');
      }
      writeType(type ?? node.type);
      _sb.write(' ');
    }
    _sb.write(getVariableName(node));
  }

  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('[');
      }
      writeVariableInitialization(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(', ');
        }
        writeVariableInitialization(node.namedParameters[index]);
      }
      _sb.write('}');
    }
    _sb.write(')');
    Statement? body = node.body;
    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();
}

class MarkingAstPrinter extends AstPrinter {
  Set<TreeNode> markThis;
  MarkingAstPrinter(super.strategy, this.markThis);

  @override
  void writeStatement(Statement node) {
    bool mark = markThis.contains(node);
    if (mark) write("***");
    super.writeStatement(node);
    if (mark) write("***");
  }

  @override
  void writeExpression(Expression node, {int? minimumPrecedence}) {
    bool mark = markThis.contains(node);
    if (mark) write("***");
    super.writeExpression(node, minimumPrecedence: minimumPrecedence);
    if (mark) write("***");
  }
}
