// Copyright (c) 2018, 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/correction/fix.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'fix_processor.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CreateConstructorTest);
    defineReflectiveTests(CreateConstructorMixinTest);
  });
}

@reflectiveTest
class CreateConstructorMixinTest extends FixProcessorTest {
  @override
  FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR;

  Future<void> test_named() async {
    await resolveTestCode('''
mixin M {}

main() {
  new M.named();
}
''');
    await assertNoFix();
  }
}

@reflectiveTest
class CreateConstructorTest extends FixProcessorTest {
  static final _text200 = 'x' * 200;

  @override
  FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR;

  Future<void> test_inLibrary_insteadOfSyntheticDefault() async {
    var a = newFile2('$testPackageLibPath/a.dart', '''
/// $_text200
class A {}
''').path;
    await resolveTestCode('''
import 'a.dart';

main() {
  new A.named(1, 2.0);
}
''');
    await assertHasFix('''
/// $_text200
class A {
  A.named(int i, double d);
}
''', target: a);
  }

  Future<void> test_inLibrary_named() async {
    var a = newFile2('$testPackageLibPath/a.dart', '''
/// $_text200
class A {}
''').path;
    await resolveTestCode('''
import 'a.dart';

main() {
  new A(1, 2.0);
}
''');
    await assertHasFix('''
/// $_text200
class A {
  A(int i, double d);
}
''', target: a);
  }

  Future<void> test_inPart_partOfName_noLibrary() async {
    await resolveTestCode('''
part of my_lib;

class A {}

void f() {
  A(0);
}
''');
    await assertNoFix();
  }

  Future<void> test_insteadOfSyntheticDefault() async {
    await resolveTestCode('''
class A {
  int field = 0;

  method() {}
}
main() {
  new A(1, 2.0);
}
''');
    await assertHasFix('''
class A {
  int field = 0;

  A(int i, double d);

  method() {}
}
main() {
  new A(1, 2.0);
}
''');
  }

  Future<void> test_mixin() async {
    verifyNoTestUnitErrors = false;
    await resolveTestCode('''
mixin M {}
void f() {
  new M(3);
}
''');
    await assertNoFix(
        errorFilter: (error) =>
            error.errorCode != CompileTimeErrorCode.MIXIN_INSTANTIATE);
  }

  Future<void> test_named() async {
    await resolveTestCode('''
class A {
  method() {}
}
main() {
  new A.named(1, 2.0);
}
''');
    await assertHasFix('''
class A {
  A.named(int i, double d);

  method() {}
}
main() {
  new A.named(1, 2.0);
}
''');
    assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
  }

  Future<void> test_named_emptyClassBody() async {
    await resolveTestCode('''
class A {}
main() {
  new A.named(1);
}
''');
    await assertHasFix('''
class A {
  A.named(int i);
}
main() {
  new A.named(1);
}
''');
    assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
  }
}
