// Copyright (c) 2014, 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.

library services.src.correction.namespace;

import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/resolver.dart';


/**
 * Returns the namespace of the given [ExportElement].
 */
Map<String, Element> getExportNamespaceForDirective(ExportElement exp) {
  Namespace namespace =
      new NamespaceBuilder().createExportNamespaceForDirective(exp);
  return namespace.definedNames;
}


/**
 * Returns the export namespace of the given [LibraryElement].
 */
Map<String, Element> getExportNamespaceForLibrary(LibraryElement library) {
  Namespace namespace =
      new NamespaceBuilder().createExportNamespaceForLibrary(library);
  return namespace.definedNames;
}


/**
 * Returns the [Element] exported from the given [LibraryElement].
 */
Element getExportedElement(LibraryElement library, String name) {
  if (library == null) {
    return null;
  }
  return getExportNamespaceForLibrary(library)[name];
}


/**
 * Returns the [ImportElement] that is referenced by [prefixNode] with
 * an [PrefixElement], maybe `null`.
 */
ImportElement getImportElement(SimpleIdentifier prefixNode) {
  if (prefixNode.parent is ImportDirective) {
    ImportDirective importDirective = prefixNode.parent;
    return importDirective.element;
  }
  ImportElementInfo info = internal_getImportElementInfo(prefixNode);
  return info != null ? info.element : null;
}

/**
 * Return the [ImportElement] that declared [prefix] and imports [element].
 *
 * [libraryElement] - the [LibraryElement] where reference is.
 * [prefix] - the import prefix, maybe `null`.
 * [element] - the referenced element.
 * [importElementsMap] - the cache of [Element]s imported by [ImportElement]s.
 */
ImportElement internal_getImportElement(LibraryElement libraryElement,
    String prefix, Element element, Map<ImportElement,
    Set<Element>> importElementsMap) {
  // validate Element
  if (element == null) {
    return null;
  }
  if (element.enclosingElement is! CompilationUnitElement) {
    return null;
  }
  LibraryElement usedLibrary = element.library;
  // find ImportElement that imports used library with used prefix
  List<ImportElement> candidates = null;
  for (ImportElement importElement in libraryElement.imports) {
    // required library
    if (importElement.importedLibrary != usedLibrary) {
      continue;
    }
    // required prefix
    PrefixElement prefixElement = importElement.prefix;
    if (prefix == null) {
      if (prefixElement != null) {
        continue;
      }
    } else {
      if (prefixElement == null) {
        continue;
      }
      if (prefix != prefixElement.name) {
        continue;
      }
    }
    // no combinators => only possible candidate
    if (importElement.combinators.length == 0) {
      return importElement;
    }
    // OK, we have candidate
    if (candidates == null) {
      candidates = [];
    }
    candidates.add(importElement);
  }
  // no candidates, probably element is defined in this library
  if (candidates == null) {
    return null;
  }
  // one candidate
  if (candidates.length == 1) {
    return candidates[0];
  }
  // ensure that each ImportElement has set of elements
  for (ImportElement importElement in candidates) {
    if (importElementsMap.containsKey(importElement)) {
      continue;
    }
    Namespace namespace =
        new NamespaceBuilder().createImportNamespaceForDirective(importElement);
    Set<Element> elements = new Set.from(namespace.definedNames.values);
    importElementsMap[importElement] = elements;
  }
  // use import namespace to choose correct one
  for (ImportElement importElement in importElementsMap.keys) {
    Set<Element> elements = importElementsMap[importElement];
    if (elements.contains(element)) {
      return importElement;
    }
  }
  // not found
  return null;
}


/**
 * Returns the [ImportElementInfo] with the [ImportElement] that is referenced
 * by [prefixNode] with a [PrefixElement], maybe `null`.
 */
ImportElementInfo internal_getImportElementInfo(SimpleIdentifier prefixNode) {
  ImportElementInfo info = new ImportElementInfo();
  // prepare environment
  AstNode parent = prefixNode.parent;
  CompilationUnit unit =
      prefixNode.getAncestor((node) => node is CompilationUnit);
  LibraryElement libraryElement = unit.element.library;
  // prepare used element
  Element usedElement = null;
  if (parent is PrefixedIdentifier) {
    PrefixedIdentifier prefixed = parent;
    if (prefixed.prefix == prefixNode) {
      usedElement = prefixed.staticElement;
      info.periodEnd = prefixed.period.end;
    }
  }
  if (parent is MethodInvocation) {
    MethodInvocation invocation = parent;
    if (invocation.target == prefixNode) {
      usedElement = invocation.methodName.staticElement;
      info.periodEnd = invocation.period.end;
    }
  }
  // we need used Element
  if (usedElement == null) {
    return null;
  }
  // find ImportElement
  String prefix = prefixNode.name;
  Map<ImportElement, Set<Element>> importElementsMap = {};
  info.element = internal_getImportElement(
      libraryElement,
      prefix,
      usedElement,
      importElementsMap);
  if (info.element == null) {
    return null;
  }
  return info;
}


/**
 * Information about [ImportElement] and place where it is referenced using
 * [PrefixElement].
 */
class ImportElementInfo {
  ImportElement element;
  int periodEnd;
}
