// 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 test.plugin.analysis_contributor;

import 'dart:async';

import 'package:analysis_server/plugin/analysis/analysis_domain.dart';
import 'package:analysis_server/plugin/analysis/navigation/navigation.dart';
import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart';
import 'package:analysis_server/plugin/analysis/occurrences/occurrences.dart';
import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/task/dart.dart';
import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';

import '../analysis_abstract.dart';
import '../utils.dart';

main() {
  initializeTestEnvironment();
  defineReflectiveTests(SetAnalysisDomainTest);
}

/**
 * This test uses [SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID] and
 * [NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID] extension points to validate
 * that plugins can listen for analysis and force sending navigation
 * notifications.
 */
@reflectiveTest
class SetAnalysisDomainTest extends AbstractAnalysisTest {
  final Set<String> parsedUnitFiles = new Set<String>();

  AnalysisNavigationParams navigationParams;
  AnalysisOccurrencesParams occurrencesParams;

  @override
  void addServerPlugins(List<Plugin> plugins) {
    var plugin = new TestSetAnalysisDomainPlugin(this);
    plugins.add(plugin);
  }

  @override
  void processNotification(Notification notification) {
    if (notification.event == ANALYSIS_NAVIGATION) {
      var params = new AnalysisNavigationParams.fromNotification(notification);
      if (params.file == testFile) {
        navigationParams = params;
      }
    }
    if (notification.event == ANALYSIS_OCCURRENCES) {
      var params = new AnalysisOccurrencesParams.fromNotification(notification);
      if (params.file == testFile) {
        occurrencesParams = params;
      }
    }
  }

  Future test_contributorIsInvoked() async {
    createProject();
    addAnalysisSubscription(AnalysisService.NAVIGATION, testFile);
    addAnalysisSubscription(AnalysisService.OCCURRENCES, testFile);
    addTestFile('// usually no navigation');
    await server.onAnalysisComplete;
    // we have PARSED_UNIT
    expect(parsedUnitFiles, contains(testFile));
    // we have an additional navigation region/target
    {
      expect(navigationParams.regions, hasLength(1));
      {
        NavigationRegion region = navigationParams.regions.single;
        expect(region.offset, 1);
        expect(region.length, 5);
        expect(region.targets.single, 0);
      }
      {
        NavigationTarget target = navigationParams.targets.single;
        expect(target.fileIndex, 0);
        expect(target.offset, 1);
        expect(target.length, 2);
        expect(target.startLine, 3);
        expect(target.startColumn, 4);
      }
      expect(navigationParams.files.single, '/testLocation.dart');
    }
    // we have additional occurrences
    {
      expect(occurrencesParams.occurrences, hasLength(1));
      Occurrences occurrences = occurrencesParams.occurrences.single;
      expect(occurrences.element.name, 'TestElement');
      expect(occurrences.length, 5);
      expect(occurrences.offsets, unorderedEquals([1, 2, 3]));
    }
  }
}

class TestNavigationContributor implements NavigationContributor {
  final SetAnalysisDomainTest test;

  TestNavigationContributor(this.test);

  @override
  void computeNavigation(NavigationCollector collector, AnalysisContext context,
      Source source, int offset, int length) {
    collector.addRegion(1, 5, ElementKind.CLASS,
        new Location('/testLocation.dart', 1, 2, 3, 4));
  }
}

class TestOccurrencesContributor implements OccurrencesContributor {
  final SetAnalysisDomainTest test;

  TestOccurrencesContributor(this.test);

  @override
  void computeOccurrences(
      OccurrencesCollector collector, AnalysisContext context, Source source) {
    Element element = new Element(ElementKind.UNKNOWN, 'TestElement', 0);
    collector.addOccurrences(new Occurrences(element, <int>[1, 2], 5));
    collector.addOccurrences(new Occurrences(element, <int>[3], 5));
  }
}

class TestSetAnalysisDomainPlugin implements Plugin {
  final SetAnalysisDomainTest test;

  TestSetAnalysisDomainPlugin(this.test);

  @override
  String get uniqueIdentifier => 'test';

  @override
  void registerExtensionPoints(RegisterExtensionPoint register) {}

  @override
  void registerExtensions(RegisterExtension register) {
    register(SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID, _setAnalysisDomain);
    register(NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID,
        new TestNavigationContributor(test));
    register(OCCURRENCES_CONTRIBUTOR_EXTENSION_POINT_ID,
        new TestOccurrencesContributor(test));
  }

  void _setAnalysisDomain(AnalysisDomain domain) {
    domain.onResultComputed(PARSED_UNIT).listen((result) {
      expect(result.context, isNotNull);
      expect(result.target, isNotNull);
      expect(result.value, isNotNull);
      Source source = result.target.source;
      test.parsedUnitFiles.add(source.fullName);
      domain.scheduleNotification(
          result.context, source, AnalysisService.NAVIGATION);
      domain.scheduleNotification(
          result.context, source, AnalysisService.OCCURRENCES);
    });
  }
}
