// 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.

import 'dart:async';

import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../support/integration_tests.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(GetTypeHierarchyTest);
  });
}

@reflectiveTest
class GetTypeHierarchyTest extends AbstractAnalysisServerIntegrationTest {
  /**
   * Pathname of the main file to run tests in.
   */
  String pathname;

  Future getTypeHierarchy_badTarget() {
    String text = r'''
main() {
  if /* target */ (true) {
    print('Hello');
  }
}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results, isNull);
    });
  }

  Future getTypeHierarchy_classElement() {
    String text = r'''
class Base {}
class Pivot /* target */ extends Base {}
class Derived extends Pivot {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(4));
      expect(results.nameToIndex['Pivot'], equals(0));
      void checkElement(String name) {
        // We don't check the full element data structure; just enough to make
        // sure that we're pointing to the correct element.
        Element element = results.items[results.nameToIndex[name]].classElement;
        expect(element.kind, equals(ElementKind.CLASS));
        expect(element.name, equals(name));
        if (name != 'Object') {
          expect(element.location.offset,
              equals(text.indexOf('class $name') + 'class '.length));
        }
      }

      checkElement('Object');
      checkElement('Base');
      checkElement('Pivot');
      checkElement('Derived');
    });
  }

  Future getTypeHierarchy_displayName() {
    String text = r'''
class Base<T> {}
class Pivot /* target */ extends Base<int> {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(3));
      expect(results.getItem('Object').displayName, isNull);
      expect(results.getItem('Base').displayName, equals('Base<int>'));
      expect(results.getItem('Pivot').displayName, isNull);
    });
  }

  Future getTypeHierarchy_functionTarget() {
    String text = r'''
main /* target */ () {
}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results, isNull);
    });
  }

  Future getTypeHierarchy_interfaces() {
    String text = r'''
class Interface1 {}
class Interface2 {}
class Pivot /* target */ implements Interface1, Interface2 {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(4));
      expect(results.pivot.interfaces, hasLength(2));
      expect(results.pivot.interfaces,
          contains(results.nameToIndex['Interface1']));
      expect(results.pivot.interfaces,
          contains(results.nameToIndex['Interface2']));
      expect(results.getItem('Object').interfaces, isEmpty);
      expect(results.getItem('Interface1').interfaces, isEmpty);
      expect(results.getItem('Interface2').interfaces, isEmpty);
    });
  }

  Future getTypeHierarchy_memberElement() {
    String text = r'''
class Base1 {
  void foo /* base1 */ ();
}
class Base2 extends Base1 {}
class Pivot extends Base2 {
  void foo /* target */ ();
}
class Derived1 extends Pivot {}
class Derived2 extends Derived1 {
  void foo /* derived2 */ ();
}''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(6));
      expect(results.getItem('Object').memberElement, isNull);
      expect(results.getItem('Base1').memberElement.location.offset,
          equals(text.indexOf('foo /* base1 */')));
      expect(results.getItem('Base2').memberElement, isNull);
      expect(results.getItem('Pivot').memberElement.location.offset,
          equals(text.indexOf('foo /* target */')));
      expect(results.getItem('Derived1').memberElement, isNull);
      expect(results.getItem('Derived2').memberElement.location.offset,
          equals(text.indexOf('foo /* derived2 */')));
    });
  }

  Future getTypeHierarchy_mixins() {
    String text = r'''
class Base {}
class Mixin1 {}
class Mixin2 {}
class Pivot /* target */ extends Base with Mixin1, Mixin2 {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(5));
      expect(results.pivot.mixins, hasLength(2));
      expect(results.pivot.mixins, contains(results.nameToIndex['Mixin1']));
      expect(results.pivot.mixins, contains(results.nameToIndex['Mixin2']));
      expect(results.getItem('Object').mixins, isEmpty);
      expect(results.getItem('Base').mixins, isEmpty);
      expect(results.getItem('Mixin1').mixins, isEmpty);
      expect(results.getItem('Mixin2').mixins, isEmpty);
    });
  }

  Future getTypeHierarchy_subclasses() {
    String text = r'''
class Base {}
class Pivot /* target */ extends Base {}
class Sub1 extends Pivot {}
class Sub2 extends Pivot {}
class Sub2a extends Sub2 {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(6));
      expect(results.pivot.subclasses, hasLength(2));
      expect(results.pivot.subclasses, contains(results.nameToIndex['Sub1']));
      expect(results.pivot.subclasses, contains(results.nameToIndex['Sub2']));
      expect(results.getItem('Object').subclasses, isEmpty);
      expect(results.getItem('Base').subclasses, isEmpty);
      expect(results.getItem('Sub1').subclasses, isEmpty);
      expect(results.getItem('Sub2').subclasses,
          equals([results.nameToIndex['Sub2a']]));
      expect(results.getItem('Sub2a').subclasses, isEmpty);
    });
  }

  Future getTypeHierarchy_superclass() {
    String text = r'''
class Base1 {}
class Base2 extends Base1 {}
class Pivot /* target */ extends Base2 {}
''';
    return typeHierarchyTest(text).then((HierarchyResults results) {
      expect(results.items, hasLength(4));
      expect(results.getItem('Object').superclass, isNull);
      expect(results.getItem('Base1').superclass,
          equals(results.nameToIndex['Object']));
      expect(results.getItem('Base2').superclass,
          equals(results.nameToIndex['Base1']));
      expect(results.getItem('Pivot').superclass,
          equals(results.nameToIndex['Base2']));
    });
  }

  Future<void> test_getTypeHierarchy() {
    pathname = sourcePath('test.dart');
    // Write a dummy file which will be overridden by tests using
    // [sendAnalysisUpdateContent].
    writeFile(pathname, '// dummy');
    standardAnalysisSetup();

    // Run all the getTypeHierarchy tests at once so that the server can take
    // advantage of incremental analysis and the test doesn't time out.
    List tests = [
      getTypeHierarchy_classElement,
      getTypeHierarchy_displayName,
      getTypeHierarchy_memberElement,
      getTypeHierarchy_superclass,
      getTypeHierarchy_interfaces,
      getTypeHierarchy_mixins,
      getTypeHierarchy_subclasses,
      getTypeHierarchy_badTarget,
      getTypeHierarchy_functionTarget
    ];
    return Future.forEach(tests, (test) => test());
  }

  Future<HierarchyResults> typeHierarchyTest(String text) async {
    int offset = text.indexOf(' /* target */') - 1;
    sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)});
    await analysisFinished;
    var result = await sendSearchGetTypeHierarchy(pathname, offset);
    if (result.hierarchyItems == null) {
      return null;
    } else {
      return new HierarchyResults(result.hierarchyItems);
    }
  }
}

/**
 * Results of a getTypeHierarchy request, processed for easier testing.
 */
class HierarchyResults {
  /**
   * The list of hierarchy items from the result.
   */
  List<TypeHierarchyItem> items;

  /**
   * The first hierarchy item from the result, which represents the pivot
   * class.
   */
  TypeHierarchyItem pivot;

  /**
   * A map from element name to item index.
   */
  Map<String, int> nameToIndex;

  /**
   * Create a [HierarchyResults] object based on the result from a
   * getTypeHierarchy request.
   */
  HierarchyResults(this.items) {
    pivot = items[0];
    nameToIndex = <String, int>{};
    for (int i = 0; i < items.length; i++) {
      nameToIndex[items[i].classElement.name] = i;
    }
  }

  /**
   * Get an item by class name.
   */
  TypeHierarchyItem getItem(String name) {
    if (nameToIndex.containsKey(name)) {
      return items[nameToIndex[name]];
    } else {
      fail('Class $name not found in hierarchy results');
    }
  }
}
