// Copyright (c) 2023, 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.

// These tests validate individual characteristics in summary
// For example, the values of methods, arguments, types, generic params etc...

@Tags(['summarizer_test'])
library;

import 'package:jnigen/src/elements/elements.dart';
import 'package:jnigen/src/summary/summary.dart';
import 'package:test/test.dart';

import 'test_util/summary_util.dart';
import 'test_util/test_util.dart';

const jnigenPackage = 'com.github.dart_lang.jnigen';
const simplePackage = '$jnigenPackage.simple_package';

extension on Classes {
  ClassDecl getClassBySimpleName(String simpleName) {
    return decls.values.firstWhere((c) => c.binaryName.endsWith(simpleName));
  }

  ClassDecl getClass(String dirName, String className) {
    return decls['$jnigenPackage.$dirName.$className']!;
  }

  ClassDecl getExampleClass() {
    return getClass('simple_package', 'Example');
  }
}

extension on ClassDecl {
  Method getMethod(String name) => methods.firstWhere((m) => m.name == name);
  Field getField(String name) => fields.firstWhere((f) => f.name == name);
}

void registerCommonTests(Classes classes) {
  test('static modifier', () {
    final example = classes.getExampleClass();
    final containsStatic = contains('static');
    final notContainsStatic = isNot(containsStatic);
    expect(example.getMethod('max4').modifiers, containsStatic);
    expect(example.getMethod('getCodename').modifiers, notContainsStatic);
    expect(example.getField('ON').modifiers, containsStatic);
    expect(example.getField('codename').modifiers, notContainsStatic);
    final nested = classes.getClassBySimpleName('Example\$Nested');
    expect(nested.modifiers, containsStatic);
    final nonStaticNested =
        classes.getClassBySimpleName('Example\$NonStaticNested');
    expect(nonStaticNested.modifiers, notContainsStatic);
  });

  test('Public, protected and private modifiers', () {
    final example = classes.getExampleClass();
    final hasPrivate = contains('private');
    final hasProtected = contains('protected');
    final hasPublic = contains('public');
    final isPrivate = allOf(hasPrivate, isNot(hasProtected), isNot(hasPublic));
    final isProtected =
        allOf(isNot(hasPrivate), hasProtected, isNot(hasPublic));
    final isPublic = allOf(isNot(hasPrivate), isNot(hasProtected), hasPublic);
    expect(example.getMethod('getNumber').modifiers, isPublic);
    expect(example.getMethod('privateMethod').modifiers, isPrivate);
    expect(example.getMethod('protectedMethod').modifiers, isProtected);
    expect(example.getField('OFF').modifiers, isPublic);
    expect(example.getField('number').modifiers, isPrivate);
    expect(example.getField('protectedField').modifiers, isProtected);
  });

  test('final modifier', () {
    final example = classes.getExampleClass();
    final isFinal = contains('final');
    expect(example.getField('PI').modifiers, isFinal);
    expect(example.getField('unusedRandom').modifiers, isFinal);
    expect(example.getField('number').modifiers, isNot(isFinal));
    expect(example.getMethod('finalMethod').modifiers, isFinal);
  });

  void assertToBeStringListType(ReferredType listType) {
    expect(listType, isA<DeclaredType>());
    final listClassType = listType as DeclaredType;
    expect(listClassType.binaryName, equals('java.util.List'));
    expect(listClassType.params, hasLength(1));
    final listTypeParam = listClassType.params[0];
    expect(listTypeParam, isA<DeclaredType>());
    expect(listTypeParam.name, equals('java.lang.String'));
  }

  test('return types', () {
    final example = classes.getExampleClass();
    expect(example.getMethod('getNumber').returnType.name, equals('int'));
    expect(example.getMethod('getName').returnType.name,
        equals('java.lang.String'));
    expect(example.getMethod('getNestedInstance').returnType.name,
        equals('$simplePackage.Example\$Nested'));
    final listType = example.getMethod('getList').returnType;
    assertToBeStringListType(listType);
  });

  test('parameter types', () {
    final example = classes.getExampleClass();
    final joinStrings = example.getMethod('joinStrings');
    final listType = joinStrings.params[0].type;
    assertToBeStringListType(listType);
    final stringType = joinStrings.params[1].type;
    expect(stringType, isA<DeclaredType>());
    expect((stringType as DeclaredType).binaryName, 'java.lang.String');
  });

  test('Parameters of several types', () {
    final example = classes.getExampleClass();
    final method = example.getMethod('methodWithSeveralParams');
    expect(method.typeParams, hasLength(1));
    expect(method.typeParams[0].name, 'T');
    expect(method.typeParams[0].bounds[0].name, 'java.lang.CharSequence');

    final charParam = method.params[0];
    expect(charParam.type, isA<PrimitiveType>());
    expect(charParam.type.name, equals('char'));

    final stringParam = method.params[1];
    expect(stringParam.type, isA<DeclaredType>());
    expect((stringParam.type as DeclaredType).binaryName,
        equals('java.lang.String'));

    final arrayParam = method.params[2];
    expect(arrayParam.type, isA<ArrayType>());
    expect((arrayParam.type as ArrayType).elementType.name, equals('int'));

    final typeVarParam = method.params[3];
    expect(typeVarParam.type, isA<TypeVar>());
    expect((typeVarParam.type as TypeVar).name, equals('T'));

    final listParam = method.params[4];
    expect(listParam.type, isA<DeclaredType>());
    final listType = listParam.type as DeclaredType;
    expect(listType.binaryName, equals('java.util.List'));
    expect(listType.params, hasLength(1));
    final tType = listType.params[0];
    expect(tType, isA<TypeVar>());
    expect((tType as TypeVar).name, equals('T'));

    final wildcardMapParam = method.params[5];
    expect(wildcardMapParam.type, isA<DeclaredType>());
    final mapType = wildcardMapParam.type as DeclaredType;
    expect(mapType.binaryName, equals('java.util.Map'));
    expect(mapType.params, hasLength(2));
    final strType = mapType.params[0];
    expect(strType.name, 'java.lang.String');
    final wildcardType = mapType.params[1];
    expect(wildcardType, isA<Wildcard>());
    expect((wildcardType as Wildcard).extendsBound?.name,
        equals('java.lang.CharSequence'));
  });

  test('typeParameters', () {
    final grandParent = classes.getClass('generics', 'GrandParent');
    final stringParent = grandParent.getMethod('stringParent');
    final returnType = stringParent.returnType as DeclaredType;
    expect(returnType.params, hasLength(2));
    expect(returnType.params[0], isA<TypeVar>());
    expect(returnType.params[1], isA<DeclaredType>());
  });

  test('superclass', () {
    final baseClass = classes.getClass('inheritance', 'BaseClass');
    expect(baseClass.typeParams, hasLength(1));
    final typeParam = baseClass.typeParams.single;
    expect(typeParam.bounds.map((b) => b.name).toList(),
        ['java.lang.CharSequence']);

    final specific = classes.getClass('inheritance', 'SpecificDerivedClass');
    expect(specific.typeParams, hasLength(0));
    expect(specific.superclass, isNotNull);
    final specificSuper = specific.superclass! as DeclaredType;
    expect(specificSuper.params[0], isA<DeclaredType>());
    expect(specificSuper.params[0].name, equals('java.lang.String'));

    final generic = classes.getClass('inheritance', 'GenericDerivedClass');
    expect(generic.typeParams, hasLength(1));
    expect(generic.typeParams[0].name, equals('T'));
    expect(generic.typeParams[0].bounds.map((b) => b.name).toList(),
        ['java.lang.CharSequence']);
    expect(generic.superclass, isNotNull);
    final genericSuper = generic.superclass! as DeclaredType;
    expect(genericSuper.params[0], isA<TypeVar>());
    expect(genericSuper.params[0].name, equals('T'));
  });

  test('constructor is included', () {
    final example = classes.getExampleClass();
    void assertOneCtorExistsWithArity(List<String> paramTypes) {
      final arityCtors = example.methods
          .where(
              (m) => m.name == '<init>' && m.params.length == paramTypes.length)
          .toList();
      expect(arityCtors, hasLength(1));
      final ctor = arityCtors[0];
      expect(ctor.params.map((p) => p.type.name), equals(paramTypes));
    }

    assertOneCtorExistsWithArity([]);
    assertOneCtorExistsWithArity(['int']);
    assertOneCtorExistsWithArity(['int', 'boolean']);
    assertOneCtorExistsWithArity(['int', 'boolean', 'java.lang.String']);
  });

  test('Overloaded methods', () {
    final methods = classes
        .getExampleClass()
        .methods
        .where((m) => m.name == 'overloaded')
        .toList();
    final signatures =
        methods.map((m) => m.params.map((p) => p.type.name).toList()).toSet();
    expect(
      signatures,
      equals({
        <String>[],
        ['int'],
        ['int', 'java.lang.String'],
        ['java.util.List'],
        ['java.util.List', 'java.lang.String'],
      }),
    );
  });

  test('Declaration type (class vs interface vs enum)', () {
    final example = classes.getExampleClass();
    expect(example.declKind, DeclKind.classKind);
    final myInterface = classes.getClass('interfaces', 'MyInterface');
    expect(myInterface.declKind, DeclKind.interfaceKind);
    final color = classes.getClass('enums', 'Colors');
    expect(color.declKind, DeclKind.enumKind);
  });

  test('Enum values', () {
    final example = classes.getExampleClass();
    expect(example.values, anyOf(isNull, isEmpty));
    final color = classes.getClass('enums', 'Colors');
    const expectedEnumValues = {'red', 'green', 'blue'};
    expect(color.values?.toSet(), expectedEnumValues);
  });

  test('Static final field values', () {
    final example = classes.getExampleClass();
    expect(example.getField('ON').defaultValue, equals(1));
    expect(example.getField('OFF').defaultValue, equals(0));
    expect(example.getField('PI').defaultValue, closeTo(3.14159, 0.001));
    expect(
        example.getField('SEMICOLON').defaultValue, equals(';'.codeUnitAt(0)));
    expect(example.getField('SEMICOLON_STRING').defaultValue, equals(';'));
  });

  test('self referencing generic parameters', () {
    final gp = classes.getClass('generics', 'GenericTypeParams');
    final typeParams = gp.typeParams;
    expect(typeParams[0].name, equals('S'));
    expect(typeParams[0].bounds.map((e) => e.name), ['java.lang.CharSequence']);
    expect(typeParams[1].name, equals('K'));
    final selfBound = typeParams[1].bounds[0];
    expect(selfBound, isA<DeclaredType>());
    expect(selfBound.name,
        equals('com.github.dart_lang.jnigen.generics.GenericTypeParams'));
    final selfBoundType = selfBound as DeclaredType;
    expect(selfBoundType.params, hasLength(2));
    expect(selfBoundType.params.map((e) => e.name), ['S', 'K']);
    expect(selfBoundType.params[0], isA<TypeVar>());
    expect(selfBoundType.params[1], isA<TypeVar>());
  });
}

void main() async {
  await checkLocallyBuiltDependencies();

  final tempDir = getTempDir('jnigen_summary_tests_');

  final sourceConfig =
      getSummaryGenerationConfig(sourcePath: [simplePackagePath]);
  final parsedFromSource = await getSummary(sourceConfig);

  final targetDir = tempDir.createTempSync('compiled_classes_test_');
  await compileJavaFiles(simplePackageDir, targetDir);
  final classConfig = getSummaryGenerationConfig(classPath: [targetDir.path]);
  final parsedFromClasses = await getSummary(classConfig);

  group('source summary', () {
    registerCommonTests(parsedFromSource);
  });

  group('compiled summary', () {
    registerCommonTests(parsedFromClasses);
  });

  group('source-based summary features', () {
    final classes = parsedFromSource;
    test('Parameter names', () {
      final example = classes.getExampleClass();
      final joinStrings = example.getMethod('joinStrings');
      expect(
          joinStrings.params.map((p) => p.name).toList(), ['values', 'delim']);
      final methodWithSeveralParams =
          example.getMethod('methodWithSeveralParams');
      expect(methodWithSeveralParams.params.map((p) => p.name).toList(),
          ['ch', 's', 'a', 't', 'lt', 'wm']);
    });

    test('Javadoc comment', () {
      final example = classes.getExampleClass();
      final joinStrings = example.getMethod('joinStrings');
      expect(joinStrings.javadoc?.comment,
          contains('Joins the strings in the list using the given delimiter.'));
    });
  });

  tearDownAll(() => tempDir.deleteSync(recursive: true));
}
