// 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:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';

/**
 * An object used to compute the list of elements referenced within a given
 * region of a compilation unit that are imported into the compilation unit's
 * library.
 */
class ImportedElementsComputer {
  /**
   * The compilation unit in which the elements are referenced.
   */
  final CompilationUnit unit;

  /**
   * The offset of the region containing the references to be returned.
   */
  final int offset;

  /**
   * The length of the region containing the references to be returned.
   */
  final int length;

  /**
   * Initialize a newly created computer to compute the list of imported
   * elements referenced in the given [unit] within the region with the given
   * [offset] and [length].
   */
  ImportedElementsComputer(this.unit, this.offset, this.length);

  /**
   * Compute and return the list of imported elements.
   */
  List<ImportedElements> compute() {
    if (_regionIncludesDirectives()) {
      return const <ImportedElements>[];
    }
    _Visitor visitor =
        new _Visitor(unit.declaredElement.library, offset, offset + length);
    unit.accept(visitor);
    return visitor.importedElements.values.toList();
  }

  /**
   * Return `true` if the region being copied includes any directives. This
   * really only needs to check for import and export directives, but excluding
   * other directives is unlikely to hurt the UX.
   */
  bool _regionIncludesDirectives() {
    NodeList<Directive> directives = unit.directives;
    if (directives.isEmpty) {
      return false;
    }
    // This might be overly restrictive if there are directives after the first
    // declaration, but that should be a rare case given that it's invalid.
    return offset < directives.last.end;
  }
}

/**
 * The visitor used by an [ImportedElementsComputer] to record the names of all
 * imported elements.
 */
class _Visitor extends UnifyingAstVisitor<void> {
  /**
   * The element representing the library containing the code being visited.
   */
  final LibraryElement containingLibrary;

  /**
   * The offset of the start of the region of text being copied.
   */
  final int startOffset;

  /**
   * The offset of the end of the region of text being copied.
   */
  final int endOffset;

  /**
   * A table mapping library path and prefix keys to the imported elements from
   * that library.
   */
  Map<String, ImportedElements> importedElements = <String, ImportedElements>{};

  /**
   * Initialize a newly created visitor to visit nodes within a specified
   * region.
   */
  _Visitor(this.containingLibrary, this.startOffset, this.endOffset);

  @override
  void visitNode(AstNode node) {
    if (node.offset <= endOffset && node.end >= startOffset) {
      node.visitChildren(this);
    }
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    if (!node.inDeclarationContext() &&
        node.offset <= endOffset &&
        node.end >= startOffset &&
        !_isConstructorDeclarationReturnType(node)) {
      Element nodeElement = node.staticElement;
      if (nodeElement != null &&
          nodeElement.enclosingElement is CompilationUnitElement) {
        LibraryElement nodeLibrary = nodeElement.library;
        String path = nodeLibrary.definingCompilationUnit.source.fullName;
        String prefix = '';
        AstNode parent = node.parent;
        if (parent is PrefixedIdentifier && parent.identifier == node) {
          prefix = _getPrefixFrom(parent.prefix);
        } else if (parent is MethodInvocation &&
            parent.methodName == node &&
            parent.target is SimpleIdentifier) {
          prefix = _getPrefixFrom(parent.target);
        }
        String key = '$prefix;$path';
        ImportedElements elements = importedElements.putIfAbsent(
            key, () => new ImportedElements(path, prefix, <String>[]));
        List<String> elementNames = elements.elements;
        String elementName = nodeElement.name;
        if (!elementNames.contains(elementName)) {
          elementNames.add(elementName);
        }
      }
    }
  }

  String _getPrefixFrom(SimpleIdentifier identifier) {
    if (identifier.offset <= endOffset && identifier.end >= startOffset) {
      Element prefixElement = identifier.staticElement;
      if (prefixElement is PrefixElement) {
        return prefixElement.name;
      }
    }
    return '';
  }

  static bool _isConstructorDeclarationReturnType(SimpleIdentifier node) {
    AstNode parent = node.parent;
    return parent is ConstructorDeclaration && parent.returnType == node;
  }
}
