// Copyright (c) 2019, 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/lsp_protocol/protocol.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'server_abstract.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(OutlineTest);
  });
}

@reflectiveTest
class OutlineTest extends AbstractLspAnalysisServerTest {
  Future<void> test_afterChange() async {
    var initialContent = 'class A {}';
    var updatedContent = 'class B {}';
    await initialize(initializationOptions: {'outline': true});

    var outlineUpdateBeforeChange = waitForOutline(mainFileUri);
    await openFile(mainFileUri, initialContent);
    var outlineBeforeChange = await outlineUpdateBeforeChange;

    var outlineUpdateAfterChange = waitForOutline(mainFileUri);
    await replaceFile(1, mainFileUri, updatedContent);
    var outlineAfterChange = await outlineUpdateAfterChange;

    expect(outlineBeforeChange, isNotNull);
    expect(outlineBeforeChange.children, hasLength(1));
    expect(outlineBeforeChange.children![0].element.name, equals('A'));

    expect(outlineAfterChange, isNotNull);
    expect(outlineAfterChange.children, hasLength(1));
    expect(outlineAfterChange.children![0].element.name, equals('B'));
  }

  Future<void> test_extensions() async {
    var initialContent = '''
extension StringExtensions on String {}
extension on String {}
    ''';
    await initialize(initializationOptions: {'outline': true});

    var outlineUpdate = waitForOutline(mainFileUri);
    await openFile(mainFileUri, initialContent);
    var outline = await outlineUpdate;

    expect(outline, isNotNull);
    expect(outline.children, hasLength(2));
    expect(outline.children![0].element.name, equals('StringExtensions'));
    expect(outline.children![1].element.name, equals('<unnamed extension>'));
  }

  Future<void> test_initial() async {
    var content = '''
/// a
class A {
  /// b
  b() {
    /// c
    c() {}
  }

  /// d
  num get d => 1;
}
''';
    await initialize(initializationOptions: {'outline': true});

    var outlineNotification = waitForOutline(mainFileUri);
    await openFile(mainFileUri, content);
    var outline = await outlineNotification;

    expect(outline, isNotNull);

    // Root node is entire document
    expect(
      outline.range,
      equals(
        Range(
          start: Position(line: 0, character: 0),
          end: Position(line: 11, character: 0),
        ),
      ),
    );
    expect(outline.children, hasLength(1));

    // class A
    var classA = outline.children![0];
    expect(classA.element.name, equals('A'));
    expect(classA.element.kind, equals('CLASS'));
    expect(
      classA.element.range,
      equals(
        Range(
          start: Position(line: 1, character: 6),
          end: Position(line: 1, character: 7),
        ),
      ),
    );
    expect(
      classA.range,
      equals(
        Range(
          start: Position(line: 0, character: 0),
          end: Position(line: 10, character: 1),
        ),
      ),
    );
    expect(
      classA.codeRange,
      equals(
        Range(
          start: Position(line: 1, character: 0),
          end: Position(line: 10, character: 1),
        ),
      ),
    );
    expect(classA.children, hasLength(2));

    // b()
    var methodB = classA.children![0];
    expect(methodB.element.name, equals('b'));
    expect(methodB.element.kind, equals('METHOD'));
    expect(
      methodB.element.range,
      equals(
        Range(
          start: Position(line: 3, character: 2),
          end: Position(line: 3, character: 3),
        ),
      ),
    );
    expect(
      methodB.range,
      equals(
        Range(
          start: Position(line: 2, character: 2),
          end: Position(line: 6, character: 3),
        ),
      ),
    );
    expect(
      methodB.codeRange,
      equals(
        Range(
          start: Position(line: 3, character: 2),
          end: Position(line: 6, character: 3),
        ),
      ),
    );
    expect(methodB.children, hasLength(1));

    // c()
    var methodC = methodB.children![0];
    expect(methodC.element.name, equals('c'));
    expect(methodC.element.kind, equals('FUNCTION'));
    expect(
      methodC.element.range,
      equals(
        Range(
          start: Position(line: 5, character: 4),
          end: Position(line: 5, character: 5),
        ),
      ),
    );
    // TODO(dantup): This one seems to be excluding its dartdoc?
    // should be line 4 for the starting range.
    // https://github.com/dart-lang/sdk/issues/39746
    expect(
      methodC.range,
      equals(
        Range(
          start: Position(line: 5, character: 4),
          end: Position(line: 5, character: 10),
        ),
      ),
    );
    expect(
      methodC.codeRange,
      equals(
        Range(
          start: Position(line: 5, character: 4),
          end: Position(line: 5, character: 10),
        ),
      ),
    );
    expect(methodC.children, isNull);

    // num get d
    var fieldD = classA.children![1];
    expect(fieldD.element.name, equals('d'));
    expect(fieldD.element.kind, equals('GETTER'));
    expect(
      fieldD.element.range,
      equals(
        Range(
          start: Position(line: 9, character: 10),
          end: Position(line: 9, character: 11),
        ),
      ),
    );
    expect(
      fieldD.range,
      equals(
        Range(
          start: Position(line: 8, character: 2),
          end: Position(line: 9, character: 17),
        ),
      ),
    );
    expect(
      fieldD.codeRange,
      equals(
        Range(
          start: Position(line: 9, character: 2),
          end: Position(line: 9, character: 17),
        ),
      ),
    );
    expect(fieldD.children, isNull);
  }

  /// As an optimization, when a file is opened but does not contain any changes
  /// from what was on disk, we skip analysis (in onOverlayCreated).
  /// We still need to ensure that notifications like Outline (which are
  /// triggered by analysis results and only sent for open files) are sent to
  /// the client.
  Future<void> test_openedWithoutChanges() async {
    var content = r'''
class A {}
''';

    // Create the file on disk so that opening the file won't re-trigger
    // analysis.
    newFile(mainFilePath, content);

    // Track when outlines arrive.
    Outline? mainOutline;
    unawaited(
      waitForOutline(mainFileUri).then((outline) => mainOutline = outline),
    );

    await Future.wait([
      initialize(initializationOptions: {'outline': true}),
      waitForAnalysisComplete(),
    ]);
    await pumpEventQueue(times: 5000);
    expect(mainOutline, isNull); // Shouldn't be sent yet, file is not open.

    await openFile(mainFileUri, content);
    await pumpEventQueue(times: 5000);
    expect(mainOutline, isNotNull); // Should have been sent now.
  }
}
