// Copyright (c) 2019, 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:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

/// An object used to build the details for each token in the code being
/// analyzed.
class TokenDetailBuilder {
  /// The list of details that were built.
  List<TokenDetails> details = [];

  /// Initialize a newly created builder.
  TokenDetailBuilder();

  /// Visit a [node] in the AST structure to build details for all of the tokens
  /// contained by that node.
  void visitNode(AstNode node) {
    for (SyntacticEntity entity in node.childEntities) {
      if (entity is Token) {
        _createDetails(entity, null, null);
      } else if (entity is SimpleIdentifier) {
        String type = _getType(entity);
        if (_isTypeName(entity)) {
          type = 'dart:core;Type<$type>';
        }
        List<String> kinds = [];
        if (entity.inDeclarationContext()) {
          kinds.add('declaration');
        } else {
          kinds.add('reference');
        }
        _createDetails(entity.token, type, kinds);
      } else if (entity is BooleanLiteral) {
        _createDetails(entity.literal, _getType(entity), null);
      } else if (entity is DoubleLiteral) {
        _createDetails(entity.literal, _getType(entity), null);
      } else if (entity is IntegerLiteral) {
        _createDetails(entity.literal, _getType(entity), null);
      } else if (entity is SimpleStringLiteral) {
        _createDetails(entity.literal, _getType(entity), null);
      } else if (entity is Comment) {
        // Ignore comments and the references within them.
      } else if (entity is AstNode) {
        visitNode(entity);
      }
    }
  }

  /// Create the details for a single [token], using the given list of [kinds].
  void _createDetails(Token token, String type, List<String> kinds) {
    details.add(new TokenDetails(token.lexeme, token.offset,
        type: type, validElementKinds: kinds));
  }

  /// Return a unique identifier for the type of the given [expression].
  String _getType(Expression expression) {
    StringBuffer buffer = new StringBuffer();
    _writeType(buffer, expression.staticType);
    return buffer.toString();
  }

  /// Return `true` if the [identifier] represents the name of a type.
  bool _isTypeName(SimpleIdentifier identifier) {
    AstNode parent = identifier.parent;
    if (parent is TypeName && identifier == parent.name) {
      return true;
    } else if (parent is PrefixedIdentifier &&
        parent.identifier == identifier) {
      AstNode parent2 = parent.parent;
      if (parent2 is TypeName && parent == parent2.name) {
        return true;
      }
    }
    return false;
  }

  /// Return a unique identifier for the type of the given [expression].
  void _writeType(StringBuffer buffer, DartType type) {
    if (type == null) {
      // This should never happen if the AST has been resolved.
      buffer.write('dynamic');
    } else if (type is FunctionType) {
      _writeType(buffer, type.returnType);
      buffer.write(' Function(');
      bool first = true;
      for (var parameter in type.parameters) {
        if (first) {
          first = false;
        } else {
          buffer.write(', ');
        }
        _writeType(buffer, parameter.type);
      }
      buffer.write(')');
    } else if (type is InterfaceType) {
      Element element = type.element;
      if (element == null || element.isSynthetic) {
        buffer.write(type.displayName);
      } else {
//        String uri = element.library.source.uri.toString();
        String name = element.name;
        if (element is ClassMemberElement) {
          String className = element.enclosingElement.name;
          // TODO(brianwilkerson) Figure out why the uri is a file: URI when it
          //  ought to be a package: URI and restore the code below to include
          //  the URI in the string.
//          buffer.write('$uri;$className;$name');
          buffer.write('$className;$name');
        } else {
//          buffer.write('$uri;$name');
          buffer.write('$name');
        }
      }
    } else {
      // Handle `void` and `dynamic`.
      buffer.write(type.displayName);
    }
  }
}
