// 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/protocol/protocol_generated.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../support/integration_tests.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(OverridesTest);
    defineReflectiveTests(OverridesTest_UseCFE);
  });
}

@reflectiveTest
class OverridesTest extends AbstractAnalysisServerIntegrationTest {
  test_overrides() {
    String pathname = sourcePath('test.dart');
    String text = r'''
abstract class Interface1 {
  method0();
  method1();
  method2();
  method3();
}

abstract class Interface2 {
  method0();
  method1();
  method4();
  method5();
}

abstract class Base {
  method0();
  method2();
  method4();
  method6();
}

class Target extends Base implements Interface1, Interface2 {
  method0() {}
  method1() {}
  method2() {}
  method3() {}
  method4() {}
  method5() {}
  method6() {}
  method7() {}
}
''';
    writeFile(pathname, text);
    standardAnalysisSetup();
    sendAnalysisSetSubscriptions({
      AnalysisService.OVERRIDES: [pathname]
    });
    List<Override> overrides;
    onAnalysisOverrides.listen((AnalysisOverridesParams params) {
      expect(params.file, equals(pathname));
      overrides = params.overrides;
    });
    return analysisFinished.then((_) {
      int targetOffset = text.indexOf('Target');
      Override findOverride(String methodName) {
        int methodOffset = text.indexOf(methodName, targetOffset);
        for (Override override in overrides) {
          if (override.offset == methodOffset) {
            return override;
          }
        }
        return null;
      }

      void checkOverrides(String methodName, bool expectedOverridesBase,
          List<String> expectedOverridesInterfaces) {
        Override override = findOverride(methodName);
        if (!expectedOverridesBase && expectedOverridesInterfaces.isEmpty) {
          // This method overrides nothing, so it should not appear in the
          // overrides list.
          expect(override, isNull);
          return;
        } else {
          expect(override, isNotNull);
        }
        expect(override.length, equals(methodName.length));
        OverriddenMember superclassMember = override.superclassMember;
        if (expectedOverridesBase) {
          expect(superclassMember.element.name, equals(methodName));
          expect(superclassMember.className, equals('Base'));
        } else {
          expect(superclassMember, isNull);
        }
        List<OverriddenMember> interfaceMembers = override.interfaceMembers;
        if (expectedOverridesInterfaces.isNotEmpty) {
          expect(interfaceMembers, isNotNull);
          Set<String> actualOverridesInterfaces = new Set<String>();
          for (OverriddenMember overriddenMember in interfaceMembers) {
            expect(overriddenMember.element.name, equals(methodName));
            String className = overriddenMember.className;
            bool wasAdded = actualOverridesInterfaces.add(className);
            expect(wasAdded, isTrue);
          }
          expect(actualOverridesInterfaces,
              equals(expectedOverridesInterfaces.toSet()));
        } else {
          expect(interfaceMembers, isNull);
        }
      }

      checkOverrides('method0', true, ['Interface1', 'Interface2']);
      checkOverrides('method1', false, ['Interface1', 'Interface2']);
      checkOverrides('method2', true, ['Interface1']);
      checkOverrides('method3', false, ['Interface1']);
      checkOverrides('method4', true, ['Interface2']);
      checkOverrides('method5', false, ['Interface2']);
      checkOverrides('method6', true, []);
      checkOverrides('method7', false, []);
    });
  }
}

@reflectiveTest
class OverridesTest_UseCFE extends OverridesTest {
  @override
  bool get useCFE => true;

  @failingTest
  @override
  test_overrides() {
    return super.test_overrides();
  }
}
