// 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.domain.analysis.notification.navigation;

import 'dart:async';

import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:unittest/unittest.dart';

import 'analysis_abstract.dart';
import 'reflective_tests.dart';


main() {
  group('notification.navigation', () {
    runReflectiveTests(AnalysisNotificationNavigationTest);
  });
}


@ReflectiveTestCase()
class AnalysisNotificationNavigationTest extends AbstractAnalysisTest {
  List<_NavigationRegion> regions;
  _NavigationRegion testRegion;
  List<_NavigationTarget> testTargets;

  void processNotification(Notification notification) {
    if (notification.event == NOTIFICATION_NAVIGATION) {
      String file = notification.getParameter(FILE);
      if (file == testFile) {
        regions = [];
        List<Map<String, Object>> regionsJson = notification.getParameter(REGIONS);
        for (Map<String, Object> regionJson in regionsJson) {
          var regionOffset = regionJson['offset'];
          var regionLength = regionJson['length'];
          List<_NavigationTarget> targets = [];
          for (Map<String, Object> targetJson in regionJson['targets']) {
            var targetFile = targetJson['file'];
            var targetOffset = targetJson['offset'];
            var targetLength = targetJson['length'];
            targets.add(new _NavigationTarget(targetFile, targetOffset, targetLength));
          }
          var region = new _NavigationRegion(regionOffset, regionLength, targets);
          regions.add(region);
        }
      }
    }
  }

  Future prepareNavigation(then()) {
    addAnalysisSubscription(AnalysisService.NAVIGATION, testFile);
    return waitForTasksFinished().then((_) {
      then();
    });
  }

  /**
   * Finds the navigation region with the given [offset] and [length].
   * If [length] is `-1`, then it is ignored.
   *
   * If [exists] is `true`, then fails if such region does not exist.
   * Otherwise remembers this it into [testRegion].
   * Also fills [testTargets] with its targets.
   *
   * If [exists] is `false`, then fails if such region exists.
   */
  void findRegion(int offset, int length, [bool exists]) {
    for (_NavigationRegion region in regions) {
      if (region.offset == offset &&
          (length == -1 || region.length == length)) {
        if (exists == false) {
          fail('Not expected to find (offset=$offset; length=$length) in\n'
               '${regions.join('\n')}');
        }
        testRegion = region;
        testTargets = region.targets;
        return;
      }
    }
    if (exists == true) {
      fail('Expected to find (offset=$offset; length=$length) in\n'
           '${regions.join('\n')}');
    }
  }

  /**
   * Validates that there is a region at the offset of [search] in [testFile].
   * If [length] is not specified explicitly, then length of an identifier
   * from [search] is used.
   */
  void assertHasRegion(String search, [int length = -1]) {
    int offset = findOffset(search);
    if (length == -1) {
      length = findIdentifierLength(search);
    }
    findRegion(offset, length, true);
  }

  /**
   * Validates that there is a region at the offset of [search] in [testFile]
   * with the length of [search].
   */
  void assertHasRegionString(String search) {
    int offset = findOffset(search);
    int length = search.length;
    findRegion(offset, length, true);
  }

  /**
   * Validates that there is a target in [testTargets]  with [testFile], at the
   * offset of [search] in [testFile], and with the given [length] or the length
   * of an leading identifier in [search].
   */
  void assertHasTarget(String search, [int length = -1]) {
    int offset = findOffset(search);
    if (length == -1) {
      length = findIdentifierLength(search);
    }
    assertHasFileTarget(testFile, offset, length);
  }

  /**
   * Validates that there is a target in [testTargets]  with [file], at [offset]
   * and with the given [length].
   */
  void assertHasFileTarget(String file, int offset, int length) {
    for (_NavigationTarget target in testTargets) {
      if (target.file == file &&
          target.offset == offset &&
          target.length == length) {
        return;
      }
    }
    fail('Expected to find target (file=$file; offset=$offset; length=$length) in\n'
         '${testRegion} in\n'
         '${regions.join('\n')}');
  }

  /**
   * Validates that there is an identifier region at [regionSearch] with target
   * at [targetSearch].
   */
  void assertHasRegionTarget(String regionSearch, String targetSearch) {
    assertHasRegion(regionSearch);
    assertHasTarget(targetSearch);
  }

  void assertHasOperatorRegion(String regionSearch, int regionLength,
                               String targetSearch, int targetLength) {
    assertHasRegion(regionSearch, regionLength);
    assertHasTarget(targetSearch, targetLength);
  }

  /**
   * Validates that there is no a region at [search] and with the given
   * [length].
   */
  void assertNoRegion(String search, int length) {
    int offset = findOffset(search);
    findRegion(offset, length, false);
  }

  /**
   * Validates that there is no a region at [search] with any length.
   */
  void assertNoRegionAt(String search) {
    int offset = findOffset(search);
    findRegion(offset, -1, false);
  }

  /**
   * Validates that there is no a region for [search] string.
   */
  void assertNoRegionString(String search) {
    int offset = findOffset(search);
    int length = search.length;
    findRegion(offset, length, false);
  }

  test_constructor_named() {
    addTestFile('''
class A {
  A.named(BBB p) {}
}
class BBB {}
''');
    return prepareNavigation(() {
      // has region for complete "A.named"
      assertHasRegionString('A.named');
      assertHasTarget('named(BBB');
      // no separate regions for "A" and "named"
      assertNoRegion('A.named(', 'A'.length);
      assertNoRegion('named(', 'named'.length);
      // validate that we don't forget to resolve parameters
      assertHasRegionTarget('BBB p', 'BBB {}');
    });
  }

  test_constructor_unnamed() {
    addTestFile('''
class A {
  A(BBB p) {}
}
class BBB {}
''');
    return prepareNavigation(() {
      // has region for complete "A.named"
      assertHasRegion("A(BBB");
      assertHasTarget("A(BBB", 0);
      // validate that we don't forget to resolve parameters
      assertHasRegionTarget('BBB p', 'BBB {}');
    });
  }

  test_fieldFormalParameter() {
    addTestFile('''
class AAA {
  int fff = 123;
  AAA(this.fff);
}
''');
    return prepareNavigation(() {
      assertHasRegionTarget('fff);', 'fff = 123');
    });
  }

  test_identifier_resolved() {
    addTestFile('''
class AAA {}
main() {
  AAA aaa = null;
  print(aaa);
}
''');
    return prepareNavigation(() {
      assertHasRegionTarget('AAA aaa', 'AAA {}');
      assertHasRegionTarget('aaa);', 'aaa = null');
      assertHasRegionTarget('main() {', 'main() {');
    });
  }

  test_identifier_unresolved() {
    addTestFile('''
main() {
  print(vvv);
}
''');
    return prepareNavigation(() {
      assertNoRegionString('vvv');
    });
  }

  test_instanceCreation_implicit() {
    addTestFile('''
class A {
}
main() {
  new A();
}
''');
    return prepareNavigation(() {
      assertHasRegionString('new A');
      assertHasTarget('A {');
    });
  }

  test_instanceCreation_named() {
    addTestFile('''
class A {
  A.named() {}
}
main() {
  new A.named();
}
''');
    return prepareNavigation(() {
      assertHasRegionString('new A.named');
      assertHasTarget('named() {}');
    });
  }

  test_instanceCreation_unnamed() {
    addTestFile('''
class A {
  A() {}
}
main() {
  new A();
}
''');
    return prepareNavigation(() {
      assertHasRegionString('new A');
      assertHasTarget("A() {}", 0);
    });
  }

  test_operator_arithmetic() {
    addTestFile('''
class A {
  A operator +(other) => null;
  A operator -() => null;
  A operator -(other) => null;
  A operator *(other) => null;
  A operator /(other) => null;
}
main() {
  var a = new A();
  a - 1;
  a + 2;
  -a; // unary
  --a;
  ++a;
  a--; // mm
  a++; // pp
  a -= 3;
  a += 4;
  a *= 5;
  a /= 6;
}
''');
    return prepareNavigation(() {
      assertHasOperatorRegion('- 1', 1, '-(other) => null', 1);
      assertHasOperatorRegion('+ 2', 1, '+(other) => null', 1);
      assertHasOperatorRegion('-a; // unary', 1, '-() => null', 1);
      assertHasOperatorRegion('--a;', 2, '-(other) => null', 1);
      assertHasOperatorRegion('++a;', 2, '+(other) => null', 1);
      assertHasOperatorRegion('--; // mm', 2, '-(other) => null', 1);
      assertHasOperatorRegion('++; // pp', 2, '+(other) => null', 1);
      assertHasOperatorRegion('-= 3', 2, '-(other) => null', 1);
      assertHasOperatorRegion('+= 4', 2, '+(other) => null', 1);
      assertHasOperatorRegion('*= 5', 2, '*(other) => null', 1);
      assertHasOperatorRegion('/= 6', 2, '/(other) => null', 1);
    });
  }

  test_operator_index() {
    addTestFile('''
class A {
  A operator +(other) => null;
}
class B {
  A operator [](index) => null;
  operator []=(index, A value) {}
}
main() {
  var b = new B();
  b[0] // [];
  b[1] = 1; // []=;
  b[2] += 2;
}
''');
    return prepareNavigation(() {
      assertHasOperatorRegion('] // []', 1, '[](index)', 2);
      assertHasOperatorRegion('] = 1;', 1, '[]=(index,', 3);
      assertHasOperatorRegion('] += 2;', 1, '[]=(index,', 3);
      assertHasOperatorRegion('+= 2;', 2, '+(other)', 1);
    });
  }

  test_partOf() {
    var libCode = 'library lib; part "test.dart";';
    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
    addTestFile('part of lib;');
    return prepareNavigation(() {
      assertHasRegionString('part of lib');
      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
    });
  }

  test_string_export() {
    var libCode = 'library lib;';
    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
    addTestFile('export "lib.dart";');
    return prepareNavigation(() {
      assertHasRegionString('export "lib.dart"');
      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
    });
  }

  test_string_export_unresolvedUri() {
    addTestFile('export "no.dart";');
    return prepareNavigation(() {
      assertNoRegionString('export "no.dart"');
    });
  }

  test_string_import() {
    var libCode = 'library lib;';
    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
    addTestFile('import "lib.dart";');
    return prepareNavigation(() {
      assertHasRegionString('import "lib.dart"');
      assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length);
    });
  }

  test_string_import_noUri() {
    addTestFile('import ;');
    return prepareNavigation(() {
      assertNoRegionAt('import ;');
    });
  }

  test_string_import_unresolvedUri() {
    addTestFile('import "no.dart";');
    return prepareNavigation(() {
      assertNoRegionString('import "no.dart"');
    });
  }

  test_string_part() {
    var unitCode = 'part of lib;  f() {}';
    var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode);
    addTestFile('''
library lib;
part "test_unit.dart";
''');
    return prepareNavigation(() {
      assertHasRegionString('part "test_unit.dart"');
      assertHasFileTarget(unitFile, 0, 0);
    });
  }

  test_string_part_unresolvedUri() {
    // TODO(scheglov) why do we throw MemoryResourceException here?
    // This Source/File does not exist.
//    addTestFile('''
//library lib;
//part "test_unit.dart";
//''');
//    return prepareNavigation(() {
//      assertNoRegionString('part "test_unit.dart"');
//    });
  }
}


class _NavigationRegion {
  final int offset;
  final int length;
  final List<_NavigationTarget> targets;

  _NavigationRegion(this.offset, this.length, this.targets);
}


class _NavigationTarget {
  final String file;
  final int offset;
  final int length;

  _NavigationTarget(this.file, this.offset, this.length);
}
