// Copyright (c) 2018, 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 'dart:convert' show json;

import 'package:kernel/ast.dart'
    show
        BoolConstant,
        BottomType,
        Class,
        Constant,
        ConstantMapEntry,
        DartType,
        DoubleConstant,
        DynamicType,
        Field,
        FunctionType,
        FutureOrType,
        InvalidType,
        InstanceConstant,
        IntConstant,
        InterfaceType,
        Library,
        ListConstant,
        MapConstant,
        NeverType,
        NullConstant,
        Nullability,
        PartialInstantiationConstant,
        Procedure,
        SetConstant,
        StringConstant,
        SymbolConstant,
        TearOffConstant,
        TreeNode,
        TypedefType,
        TypeLiteralConstant,
        TypeParameter,
        TypeParameterType,
        UnevaluatedConstant,
        VoidType;

import 'package:kernel/visitor.dart' show ConstantVisitor, DartTypeVisitor;

import '../denylisted_classes.dart' show denylistedCoreClasses;

import '../fasta_codes.dart'
    show Message, templateTypeOrigin, templateTypeOriginWithFileUri;

import '../problems.dart' show unsupported;

/// A pretty-printer for Kernel types and constants with the ability to label
/// raw types with numeric markers in Dart comments (e.g. `/*1*/`) to
/// distinguish different types with the same name. This is used in diagnostic
/// messages to indicate the origins of types occurring in the message.
class TypeLabeler implements DartTypeVisitor<void>, ConstantVisitor<void> {
  final List<LabeledNode> names = <LabeledNode>[];
  final Map<String, List<LabeledNode>> nameMap = <String, List<LabeledNode>>{};
  final bool printNullability;

  List<Object> result;

  TypeLabeler(this.printNullability);

  /// Pretty-print a type.
  /// When all types and constants appearing in the same message have been
  /// pretty-printed, the returned list can be converted to its string
  /// representation (with labels on duplicated names) by the `join()` method.
  List<Object> labelType(DartType type) {
    // TODO(askesc): Remove null check when we are completely null clean here.
    if (type == null) return ["null-type"];
    result = [];
    type.accept(this);
    return result;
  }

  /// Pretty-print a constant.
  /// When all types and constants appearing in the same message have been
  /// pretty-printed, the returned list can be converted to its string
  /// representation (with labels on duplicated names) by the `join()` method.
  List<Object> labelConstant(Constant constant) {
    // TODO(askesc): Remove null check when we are completely null clean here.
    if (constant == null) return ["null-constant"];
    result = [];
    constant.accept(this);
    return result;
  }

  /// Get a textual description of the origins of the raw types appearing in
  /// types and constants that have been pretty-printed using this labeler.
  String get originMessages {
    StringBuffer messages = new StringBuffer();
    for (LabeledNode name in names) {
      messages.write(name.originMessage);
    }
    return messages.toString();
  }

  // We don't have access to coreTypes here, so we have our own Object check.
  static bool isObject(DartType type) {
    if (type is InterfaceType && type.classNode.name == 'Object') {
      Uri importUri = type.classNode.enclosingLibrary.importUri;
      return importUri.scheme == 'dart' && importUri.path == 'core';
    }
    return false;
  }

  LabeledNode nameForEntity(
      TreeNode node, String nodeName, Uri importUri, Uri fileUri) {
    List<LabeledNode> labelsForName = nameMap[nodeName];
    if (labelsForName == null) {
      // First encountered entity with this name
      LabeledNode name =
          new LabeledNode(node, nodeName, importUri, fileUri, this);
      names.add(name);
      nameMap[nodeName] = [name];
      return name;
    } else {
      for (LabeledNode entityForName in labelsForName) {
        if (entityForName.node == node) {
          // Previously encountered entity
          return entityForName;
        }
      }
      // New entity with name that was previously encountered
      LabeledNode name =
          new LabeledNode(node, nodeName, importUri, fileUri, this);
      names.add(name);
      labelsForName.add(name);
      return name;
    }
  }

  void addNullability(Nullability nullability) {
    if (printNullability) {
      if (nullability == Nullability.nullable) {
        result.add("?");
      }
    }
  }

  void defaultDartType(DartType type) {}
  void visitTypedefType(TypedefType node) {}

  void visitInvalidType(InvalidType node) {
    // TODO(askesc): Throw internal error if InvalidType appears in diagnostics.
    result.add("invalid-type");
  }

  void visitBottomType(BottomType node) {
    // TODO(askesc): Throw internal error if BottomType appears in diagnostics.
    result.add("bottom-type");
  }

  void visitNeverType(NeverType node) {
    result.add("Never");
    addNullability(node.declaredNullability);
  }

  void visitDynamicType(DynamicType node) {
    result.add("dynamic");
  }

  void visitVoidType(VoidType node) {
    result.add("void");
  }

  void visitTypeParameterType(TypeParameterType node) {
    TreeNode parent = node.parameter;
    while (parent is! Library && parent != null) {
      parent = parent.parent;
    }
    // Note that this can be null if, for instance, the erroneous code is not
    // actually in the tree - then we don't know where it comes from!
    Library enclosingLibrary = parent;

    result.add(nameForEntity(
        node.parameter,
        node.parameter.name,
        enclosingLibrary == null ? unknownUri : enclosingLibrary.importUri,
        enclosingLibrary == null ? unknownUri : enclosingLibrary.fileUri));
    addNullability(node.declaredNullability);
  }

  void visitFunctionType(FunctionType node) {
    node.returnType.accept(this);
    result.add(" Function");
    if (node.typeParameters.isNotEmpty) {
      result.add("<");
      bool first = true;
      for (TypeParameter param in node.typeParameters) {
        if (!first) result.add(", ");
        result.add(param.name);
        if (isObject(param.bound) && param.defaultType is DynamicType) {
          // Bound was not specified, and therefore should not be printed.
        } else {
          result.add(" extends ");
          param.bound.accept(this);
        }
        first = false;
      }
      result.add(">");
    }
    result.add("(");
    bool first = true;
    for (int i = 0; i < node.requiredParameterCount; i++) {
      if (!first) result.add(", ");
      node.positionalParameters[i].accept(this);
      first = false;
    }
    if (node.positionalParameters.length > node.requiredParameterCount) {
      if (node.requiredParameterCount > 0) result.add(", ");
      result.add("[");
      first = true;
      for (int i = node.requiredParameterCount;
          i < node.positionalParameters.length;
          i++) {
        if (!first) result.add(", ");
        node.positionalParameters[i].accept(this);
        first = false;
      }
      result.add("]");
    }
    if (node.namedParameters.isNotEmpty) {
      if (node.positionalParameters.isNotEmpty) result.add(", ");
      result.add("{");
      first = true;
      for (int i = 0; i < node.namedParameters.length; i++) {
        if (!first) result.add(", ");
        node.namedParameters[i].type.accept(this);
        result.add(" ${node.namedParameters[i].name}");
        first = false;
      }
      result.add("}");
    }
    result.add(")");
    addNullability(node.nullability);
  }

  void visitInterfaceType(InterfaceType node) {
    Class classNode = node.classNode;
    result.add(nameForEntity(
        classNode,
        classNode.name,
        classNode.enclosingLibrary.importUri,
        classNode.enclosingLibrary.fileUri));
    if (node.typeArguments.isNotEmpty) {
      result.add("<");
      bool first = true;
      for (DartType typeArg in node.typeArguments) {
        if (!first) result.add(", ");
        typeArg.accept(this);
        first = false;
      }
      result.add(">");
    }
    if (classNode.name == 'Null' &&
        classNode.enclosingLibrary.importUri.scheme == 'dart' &&
        classNode.enclosingLibrary.importUri.path == 'core') {
      // Don't print nullability on `Null`.
      return;
    }
    addNullability(node.nullability);
  }

  void visitFutureOrType(FutureOrType node) {
    result.add("FutureOr<");
    node.typeArgument.accept(this);
    result.add(">");
    addNullability(node.declaredNullability);
  }

  void defaultConstant(Constant node) {}

  void visitNullConstant(NullConstant node) {
    result.add('${node.value}');
  }

  void visitBoolConstant(BoolConstant node) {
    result.add('${node.value}');
  }

  void visitIntConstant(IntConstant node) {
    result.add('${node.value}');
  }

  void visitDoubleConstant(DoubleConstant node) {
    result.add('${node.value}');
  }

  void visitSymbolConstant(SymbolConstant node) {
    String text = node.libraryReference != null
        ? '#${node.libraryReference.asLibrary.importUri}::${node.name}'
        : '#${node.name}';
    result.add(text);
  }

  void visitStringConstant(StringConstant node) {
    result.add(json.encode(node.value));
  }

  void visitInstanceConstant(InstanceConstant node) {
    new InterfaceType(node.classNode, Nullability.legacy, node.typeArguments)
        .accept(this);
    result.add(" {");
    bool first = true;
    for (Field field in node.classNode.fields) {
      if (field.isStatic) continue;
      if (!first) result.add(", ");
      result.add("${field.name}: ");
      node.fieldValues[field.reference].accept(this);
      first = false;
    }
    result.add("}");
  }

  void visitListConstant(ListConstant node) {
    result.add("<");
    node.typeArgument.accept(this);
    result.add(">[");
    bool first = true;
    for (Constant constant in node.entries) {
      if (!first) result.add(", ");
      constant.accept(this);
      first = false;
    }
    result.add("]");
  }

  void visitSetConstant(SetConstant node) {
    result.add("<");
    node.typeArgument.accept(this);
    result.add(">{");
    bool first = true;
    for (Constant constant in node.entries) {
      if (!first) result.add(", ");
      constant.accept(this);
      first = false;
    }
    result.add("}");
  }

  void visitMapConstant(MapConstant node) {
    result.add("<");
    node.keyType.accept(this);
    result.add(", ");
    node.valueType.accept(this);
    result.add(">{");
    bool first = true;
    for (ConstantMapEntry entry in node.entries) {
      if (!first) result.add(", ");
      entry.key.accept(this);
      result.add(": ");
      entry.value.accept(this);
      first = false;
    }
    result.add("}");
  }

  void visitTearOffConstant(TearOffConstant node) {
    Procedure procedure = node.procedure;
    Class classNode = procedure.enclosingClass;
    if (classNode != null) {
      result.add(nameForEntity(
          classNode,
          classNode.name,
          classNode.enclosingLibrary.importUri,
          classNode.enclosingLibrary.fileUri));
      result.add(".");
    }
    result.add(procedure.name.text);
  }

  void visitPartialInstantiationConstant(PartialInstantiationConstant node) {
    node.tearOffConstant.accept(this);
    if (node.types.isNotEmpty) {
      result.add("<");
      bool first = true;
      for (DartType typeArg in node.types) {
        if (!first) result.add(", ");
        typeArg.accept(this);
        first = false;
      }
      result.add(">");
    }
  }

  void visitTypeLiteralConstant(TypeLiteralConstant node) {
    node.type.accept(this);
  }

  void visitUnevaluatedConstant(UnevaluatedConstant node) {
    unsupported('printing unevaluated constants', -1, null);
  }
}

final Uri unknownUri = Uri.parse("unknown");

class LabeledNode {
  final TreeNode node;
  final TypeLabeler typeLabeler;
  final String name;
  final Uri importUri;
  final Uri fileUri;

  LabeledNode(
      this.node, this.name, this.importUri, this.fileUri, this.typeLabeler);

  String toString() {
    List<LabeledNode> entityForName = typeLabeler.nameMap[name];
    if (entityForName.length == 1) {
      return name;
    }
    return "$name/*${entityForName.indexOf(this) + 1}*/";
  }

  String get originMessage {
    if (importUri.scheme == 'dart' && importUri.path == 'core') {
      if (node is Class && denylistedCoreClasses.contains(name)) {
        // Denylisted core class. Only print if ambiguous.
        List<LabeledNode> entityForName = typeLabeler.nameMap[name];
        if (entityForName.length == 1) {
          return "";
        }
      }
    }
    if (importUri == unknownUri || node is! Class) {
      // We don't know where it comes from and/or it's not a class.
      // Only print if ambiguous.
      List<LabeledNode> entityForName = typeLabeler.nameMap[name];
      if (entityForName.length == 1) {
        return "";
      }
    }
    Message message = (importUri == fileUri || importUri.scheme == 'dart')
        ? templateTypeOrigin.withArguments(toString(), importUri)
        : templateTypeOriginWithFileUri.withArguments(
            toString(), importUri, fileUri);
    return "\n - " + message.message;
  }
}
