// 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 analysis.type_hierarhy;

import 'dart:async';
import 'dart:collection';

import 'package:analysis_server/src/protocol_server.dart' show
    TypeHierarchyItem, newElement_fromEngine;
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/src/generated/element.dart';

/**
 * A computer for a type hierarchy of an [Element].
 */
class TypeHierarchyComputer {
  final SearchEngine _searchEngine;

  ElementKind _pivotKind;
  String _pivotName;

  final List<TypeHierarchyItem> _items = <TypeHierarchyItem>[];
  final List<ClassElement> _itemClassElements = <ClassElement>[];
  final Map<Element, TypeHierarchyItem> _elementItemMap =
      new HashMap<Element, TypeHierarchyItem>();

  TypeHierarchyComputer(this._searchEngine);

  /**
   * Returns the computed type hierarchy, maybe `null`.
   */
  Future<List<TypeHierarchyItem>> compute(Element element) {
    _pivotKind = element.kind;
    _pivotName = element.name;
    if (element is ExecutableElement &&
        element.enclosingElement is ClassElement) {
      element = element.enclosingElement;
    }
    if (element is ClassElement) {
      InterfaceType type = element.type;
      _createSuperItem(type);
      return _createSubclasses(_items[0], 0, type).then((_) {
        return new Future.value(_items);
      });
    }
    return new Future.value(null);
  }

  Future _createSubclasses(TypeHierarchyItem item, int itemId,
      InterfaceType type) {
    var future = getDirectSubClasses(_searchEngine, type.element);
    return future.then((Set<ClassElement> subElements) {
      List<int> subItemIds = <int>[];
      for (ClassElement subElement in subElements) {
        // check for recursion
        TypeHierarchyItem subItem = _elementItemMap[subElement];
        if (subItem != null) {
          int id = _items.indexOf(subItem);
          subItem.subclasses.add(id);
          continue;
        }
        // create a subclass item
        ExecutableElement subMemberElement = _findMemberElement(subElement);
        subItem = new TypeHierarchyItem(
            newElement_fromEngine(subElement),
            memberElement: subMemberElement != null ?
                newElement_fromEngine(subMemberElement) :
                null,
            superclass: itemId);
        int subItemId = _items.length;
        // remember
        _elementItemMap[subElement] = subItem;
        _items.add(subItem);
        _itemClassElements.add(subElement);
        // add to hierarchy
        item.subclasses.add(subItemId);
        subItemIds.add(subItemId);
      }
      // compute subclasses of subclasses
      return Future.forEach(subItemIds, (int subItemId) {
        TypeHierarchyItem subItem = _items[subItemId];
        ClassElement subItemElement = _itemClassElements[subItemId];
        InterfaceType subType = subItemElement.type;
        return _createSubclasses(subItem, subItemId, subType);
      });
    });
  }

  int _createSuperItem(InterfaceType type) {
    // check for recursion
    TypeHierarchyItem item = _elementItemMap[type.element];
    if (item != null) {
      return _items.indexOf(item);
    }
    // create an empty item now
    int itemId;
    {
      String displayName = null;
      if (type.typeArguments.isNotEmpty) {
        displayName = type.toString();
      }
      ClassElement classElement = type.element;
      ExecutableElement memberElement = _findMemberElement(classElement);
      item = new TypeHierarchyItem(
          newElement_fromEngine(classElement),
          displayName: displayName,
          memberElement: memberElement != null ?
              newElement_fromEngine(memberElement) :
              null);
      _elementItemMap[classElement] = item;
      itemId = _items.length;
      _items.add(item);
      _itemClassElements.add(classElement);
    }
    // superclass
    {
      InterfaceType superType = type.superclass;
      if (superType != null) {
        item.superclass = _createSuperItem(superType);
      }
    }
    // mixins
    type.mixins.forEach((InterfaceType type) {
      int id = _createSuperItem(type);
      item.mixins.add(id);
    });
    // interfaces
    type.interfaces.forEach((InterfaceType type) {
      int id = _createSuperItem(type);
      item.interfaces.add(id);
    });
    // done
    return itemId;
  }

  ExecutableElement _findMemberElement(ClassElement classElement) {
    if (_pivotKind == ElementKind.METHOD) {
      return classElement.getMethod(_pivotName);
    }
    if (_pivotKind == ElementKind.GETTER) {
      return classElement.getGetter(_pivotName);
    }
    if (_pivotKind == ElementKind.SETTER) {
      return classElement.getSetter(_pivotName);
    }
    return null;
  }
}
