// 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 'package:analysis_server/src/protocol_server.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'available_suggestions_base.dart';

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

@reflectiveTest
class AvailableSuggestionSetsTest extends AvailableSuggestionsBase {
  test_notifications_whenFileChanges() async {
    var path = convertPath('/home/test/lib/a.dart');
    var uriStr = 'package:test/a.dart';

    // No file initially, so no set.
    expect(uriToSetMap.keys, isNot(contains(uriStr)));

    // Create the file, should get the set.
    {
      newFile(path, content: r'''
class A {}
''');
      var set = await waitForSetWithUri(uriStr);
      expect(set.items.map((d) => d.label), contains('A'));
    }

    // Update the file, should get the updated set.
    {
      newFile(path, content: r'''
class B {}
''');
      removeSet(uriStr);
      var set = await waitForSetWithUri(uriStr);
      expect(set.items.map((d) => d.label), contains('B'));
    }

    // Delete the file, the set should be removed.
    deleteFile(path);
    waitForSetWithUriRemoved(uriStr);
  }

  test_suggestion_class() async {
    var path = convertPath('/home/test/lib/a.dart');
    var uriStr = 'package:test/a.dart';

    newFile(path, content: r'''
class A {}
''');

    var set = await waitForSetWithUri(uriStr);
    assertJsonText(_getSuggestion(set, 'A'), '''
{
  "label": "A",
  "element": {
    "kind": "CLASS",
    "name": "A",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 6,
      "length": 0,
      "startLine": 1,
      "startColumn": 7
    },
    "flags": 0
  },
  "relevanceTags": [
    "package:test/a.dart::A"
  ]
}
''');
  }

  test_suggestion_enum() async {
    var path = convertPath('/home/test/lib/a.dart');
    var uriStr = 'package:test/a.dart';

    newFile(path, content: r'''
enum MyEnum {
  aaa,
  bbb,
}
''');

    var set = await waitForSetWithUri(uriStr);
    assertJsonText(_getSuggestion(set, 'MyEnum'), '''
{
  "label": "MyEnum",
  "element": {
    "kind": "ENUM",
    "name": "MyEnum",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 5,
      "length": 0,
      "startLine": 1,
      "startColumn": 6
    },
    "flags": 0
  },
  "relevanceTags": [
    "package:test/a.dart::MyEnum"
  ]
}
''');
    assertJsonText(_getSuggestion(set, 'MyEnum.aaa'), '''
{
  "label": "MyEnum.aaa",
  "element": {
    "kind": "ENUM_CONSTANT",
    "name": "aaa",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 16,
      "length": 0,
      "startLine": 2,
      "startColumn": 3
    },
    "flags": 0
  },
  "relevanceTags": [
    "package:test/a.dart::MyEnum"
  ]
}
''');
    assertJsonText(_getSuggestion(set, 'MyEnum.bbb'), '''
{
  "label": "MyEnum.bbb",
  "element": {
    "kind": "ENUM_CONSTANT",
    "name": "bbb",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 23,
      "length": 0,
      "startLine": 3,
      "startColumn": 3
    },
    "flags": 0
  },
  "relevanceTags": [
    "package:test/a.dart::MyEnum"
  ]
}
''');
  }

  test_suggestion_topLevelVariable() async {
    var path = convertPath('/home/test/lib/a.dart');
    var uriStr = 'package:test/a.dart';

    newFile(path, content: r'''
var boolV = false;
var intV = 0;
var doubleV = 0.1;
var stringV = 'hi';
''');

    var set = await waitForSetWithUri(uriStr);
    assertJsonText(_getSuggestion(set, 'boolV'), '''
{
  "label": "boolV",
  "element": {
    "kind": "TOP_LEVEL_VARIABLE",
    "name": "boolV",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 4,
      "length": 0,
      "startLine": 1,
      "startColumn": 5
    },
    "flags": 0,
    "returnType": ""
  },
  "relevanceTags": [
    "dart:core::bool"
  ]
}
''');
    assertJsonText(_getSuggestion(set, 'intV'), '''
{
  "label": "intV",
  "element": {
    "kind": "TOP_LEVEL_VARIABLE",
    "name": "intV",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 23,
      "length": 0,
      "startLine": 2,
      "startColumn": 5
    },
    "flags": 0,
    "returnType": ""
  },
  "relevanceTags": [
    "dart:core::int"
  ]
}
''');
    assertJsonText(_getSuggestion(set, 'doubleV'), '''
{
  "label": "doubleV",
  "element": {
    "kind": "TOP_LEVEL_VARIABLE",
    "name": "doubleV",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 37,
      "length": 0,
      "startLine": 3,
      "startColumn": 5
    },
    "flags": 0,
    "returnType": ""
  },
  "relevanceTags": [
    "dart:core::double"
  ]
}
''');
    assertJsonText(_getSuggestion(set, 'stringV'), '''
{
  "label": "stringV",
  "element": {
    "kind": "TOP_LEVEL_VARIABLE",
    "name": "stringV",
    "location": {
      "file": ${jsonOfPath(path)},
      "offset": 56,
      "length": 0,
      "startLine": 4,
      "startColumn": 5
    },
    "flags": 0,
    "returnType": ""
  },
  "relevanceTags": [
    "dart:core::String"
  ]
}
''');
  }

  static AvailableSuggestion _getSuggestion(
      AvailableSuggestionSet set, String label) {
    return set.items.singleWhere((s) => s.label == label);
  }
}
