// 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 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide ElementKind;
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'abstract_refactoring.dart';

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

@reflectiveTest
class ConvertGetterToMethodTest extends RefactoringTest {
  @override
  late ConvertGetterToMethodRefactoring refactoring;

  Future<void> test_change_function() async {
    await indexTestUnit('''
int get test => 42;
main() {
  var a = test;
  var b = test;
}
''');
    var element = findElement.topGet('test');
    _createRefactoringForElement(
      element,
    );
    // apply refactoring
    return _assertSuccessfulRefactoring('''
int test() => 42;
main() {
  var a = test();
  var b = test();
}
''');
  }

  Future<void> test_change_method() async {
    await indexTestUnit('''
class A {
  int get test => 1;
}
class B extends A {
  int get test => 2;
}
class C extends B {
  int get test => 3;
}
class D extends A {
  int get test => 4;
}
void f(A a, B b, C c, D d) {
  var va = a.test;
  var vb = b.test;
  var vc = c.test;
  var vd = d.test;
}
''');
    var element = findElement.getter('test', of: 'B');
    _createRefactoringForElement(element);
    // apply refactoring
    return _assertSuccessfulRefactoring('''
class A {
  int test() => 1;
}
class B extends A {
  int test() => 2;
}
class C extends B {
  int test() => 3;
}
class D extends A {
  int test() => 4;
}
void f(A a, B b, C c, D d) {
  var va = a.test();
  var vb = b.test();
  var vc = c.test();
  var vd = d.test();
}
''');
  }

  Future<void> test_change_multipleFiles() async {
    await indexUnit('/home/test/lib/other.dart', r'''
class A {
  int get test => 1;
}
''');
    await indexTestUnit('''
import 'other.dart';
class B extends A {
  int get test => 2;
}
void f(A a, B b) {
  a.test;
  b.test;
}
''');
    var element = findElement.getter('test', of: 'B');
    _createRefactoringForElement(element);
    // apply refactoring
    return _assertSuccessfulRefactoring('''
import 'other.dart';
class B extends A {
  int test() => 2;
}
void f(A a, B b) {
  a.test();
  b.test();
}
''');
  }

  Future<void> test_checkInitialConditions_syntheticGetter() async {
    await indexTestUnit('''
int test = 42;
main() {
}
''');
    var element = findElement.topGet('test');
    _createRefactoringForElement(element);
    // check conditions
    await _assertInitialConditions_fatal(
        'Only explicit getters can be converted to methods.');
  }

  Future _assertInitialConditions_fatal(String message) async {
    var status = await refactoring.checkInitialConditions();
    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
        expectedMessage: message);
  }

  /// Checks that all conditions are OK and the result of applying [refactoring]
  /// change to [testUnit] is [expectedCode].
  Future _assertSuccessfulRefactoring(String expectedCode) async {
    await assertRefactoringConditionsOK();
    var refactoringChange = await refactoring.createChange();
    this.refactoringChange = refactoringChange;
    assertTestChangeResult(expectedCode);
  }

  void _createRefactoringForElement(PropertyAccessorElement element) {
    refactoring = ConvertGetterToMethodRefactoring(
        searchEngine, testAnalysisResult.session, element);
  }
}
