// 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:args/args.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/ir/annotations.dart';
import 'package:compiler/src/js_backend/native_data.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
import 'package:kernel/ast.dart' as ir;

import '../helpers/args_helper.dart';
import 'package:compiler/src/util/memory_compiler.dart';

const String pathPrefix = 'sdk/tests/web_2/native/';

const Map<String, String> source = {
  '$pathPrefix/main.dart': '''

library lib;

import 'package:meta/dart2js.dart';

import 'jslib1.dart';
import 'jslib2.dart';
import 'nativelib.dart';

@pragma('dart2js:noInline')
method1() {}

@noInline
method2() {}

@pragma(const String.fromEnvironment('foo', defaultValue: 'dart2js:tryInline'))
method3() {}

@tryInline
method4() {}

main() {
  method1();
  method2();
  method3();
  method4();
  JsClass1()..jsMethod1()..jsMethod2();
  JsClass2();
  jsMethod3();
  NativeClass1()..nativeMethod()..nativeField;
  NativeClass2()..nativeField;
  NativeClass3()..nativeMethod()..nativeGetter;
  nativeMethod();
}
''',
  '$pathPrefix/jslib1.dart': '''

@JS('lib1')
library lib1;

import 'package:js/js.dart';

@JS('JsInteropClass1')
class JsClass1 {
  @JS('jsInteropMethod1')
  external jsMethod1();

  external jsMethod2();
}

''',
  '$pathPrefix/jslib2.dart': '''

@JS()
library lib2;

import 'package:js/js.dart';

@JS()
@anonymous
class JsClass2 {
}

@JS('jsInteropMethod3')
external jsMethod3();

external jsMethod4();
''',
  '$pathPrefix/nativelib.dart': '''
library lib3;

import 'dart:_js_helper';

@Native('Class1')
class NativeClass1 {
  @JSName('field1')
  var nativeField;

  @JSName('method1')
  nativeMethod() native;
}

@Native('Class2,!nonleaf')
class NativeClass2 {
  @JSName('field2')
  var nativeField;
}

@Native('Class3a,Class3b')
class NativeClass3 {

  @JSName('method2')
  get nativeGetter native;

  @Creates('String')
  @Returns('int')
  nativeMethod() native;
}

@JSName('method3')
nativeMethod() native;
''',
};

const Map<String, String> expectedNativeClassNames = {
  '$pathPrefix/nativelib.dart::NativeClass1': 'Class1',
  '$pathPrefix/nativelib.dart::NativeClass2': 'Class2,!nonleaf',
  '$pathPrefix/nativelib.dart::NativeClass3': 'Class3a,Class3b',
};

const Map<String, String> expectedNativeMemberNames = {
  '$pathPrefix/nativelib.dart::NativeClass1::nativeField': 'field1',
  '$pathPrefix/nativelib.dart::NativeClass1::nativeMethod': 'method1',
  '$pathPrefix/nativelib.dart::NativeClass2::nativeField': 'field2',
  '$pathPrefix/nativelib.dart::NativeClass3::nativeGetter': 'method2',
  '$pathPrefix/nativelib.dart::nativeMethod': 'method3',
};

const Map<String, String> expectedCreates = {
  '$pathPrefix/nativelib.dart::NativeClass3::nativeMethod': 'String',
};

const Map<String, String> expectedReturns = {
  '$pathPrefix/nativelib.dart::NativeClass3::nativeMethod': 'int',
};

const Map<String, String> expectedJsInteropLibraryNames = {
  '$pathPrefix/jslib1.dart': 'lib1',
  '$pathPrefix/jslib2.dart': '',
};

const Map<String, String> expectedJsInteropClassNames = {
  '$pathPrefix/jslib1.dart::JsClass1': 'JsInteropClass1',
  '$pathPrefix/jslib2.dart::JsClass2': '',
};

const Map<String, String> expectedJsInteropMemberNames = {
  '$pathPrefix/jslib1.dart::JsClass1::jsMethod1': 'jsInteropMethod1',
  '$pathPrefix/jslib2.dart::jsMethod3': 'jsInteropMethod3',
};

const Set<String> expectedAnonymousJsInteropClasses = {
  '$pathPrefix/jslib2.dart::JsClass2',
};

const Set<String> expectedNoInlineMethods = {
  '$pathPrefix/main.dart::method1',
  '$pathPrefix/main.dart::method2',
};

const Set<String> expectedTryInlineMethods = {
  '$pathPrefix/main.dart::method3',
  '$pathPrefix/main.dart::method4',
};

main(List<String> args) {
  ArgParser argParser = createArgParser();

  asyncTest(() async {
    ArgResults argResults = argParser.parse(args);
    Uri? librariesSpecificationUri = getLibrariesSpec(argResults);
    Uri? packageConfig = getPackages(argResults);
    List<String> options = getOptions(argResults);

    runTest({required bool useIr}) async {
      CompilationResult result = await runCompiler(
          entryPoint: Uri.parse('memory:$pathPrefix/main.dart'),
          memorySourceFiles: source,
          packageConfig: packageConfig,
          librariesSpecificationUri: librariesSpecificationUri,
          options: options);
      Expect.isTrue(result.isSuccess);
      Compiler compiler = result.compiler;
      KernelFrontendStrategy frontendStrategy = compiler.frontendStrategy;
      KernelToElementMap elementMap = frontendStrategy.elementMap;
      ir.Component component = elementMap.env.mainComponent;
      IrAnnotationData annotationData =
          frontendStrategy.irAnnotationDataForTesting;

      void testAll(NativeData nativeData) {
        void testMember(String idPrefix, ir.Member member,
            {required bool implicitJsInteropMember,
            required bool implicitNativeMember}) {
          if (memberIsIgnorable(member)) return;
          String memberId = '$idPrefix::${member.name.text}';
          MemberEntity memberEntity = elementMap.getMember(member);

          String? expectedJsInteropMemberName =
              expectedJsInteropMemberNames[memberId];
          String? expectedNativeMemberName =
              expectedNativeMemberNames[memberId];
          Set<String> expectedPragmaNames = {};
          if (expectedNoInlineMethods.contains(memberId)) {
            expectedPragmaNames.add('dart2js:noInline');
          }
          if (expectedTryInlineMethods.contains(memberId)) {
            expectedPragmaNames.add('dart2js:tryInline');
          }

          String? expectedCreatesText = expectedCreates[memberId];
          String? expectedReturnsText = expectedReturns[memberId];

          if (useIr) {
            Expect.equals(
                expectedJsInteropMemberName,
                annotationData.getJsInteropMemberName(member),
                "Unexpected js interop member name from IR for $member, "
                "id: $memberId");

            Expect.equals(
                expectedNativeMemberName,
                annotationData.getNativeMemberName(member),
                "Unexpected js interop member name from IR for $member, "
                "id: $memberId");

            List<PragmaAnnotationData> pragmaAnnotations =
                annotationData.getMemberPragmaAnnotationData(member);
            Set<String> pragmaNames =
                pragmaAnnotations.map((d) => d.name).toSet();
            Expect.setEquals(expectedPragmaNames, pragmaNames,
                "Unexpected pragmas from IR for $member, " "id: $memberId");

            List<String> createsAnnotations =
                annotationData.getCreatesAnnotations(member);
            Expect.equals(
                expectedCreatesText,
                createsAnnotations.isEmpty
                    ? null
                    : createsAnnotations.join(','),
                "Unexpected create annotations from IR for $member, "
                "id: $memberId");

            List<String> returnsAnnotations =
                annotationData.getReturnsAnnotations(member);
            Expect.equals(
                expectedReturnsText,
                returnsAnnotations.isEmpty
                    ? null
                    : returnsAnnotations.join(','),
                "Unexpected returns annotations from IR for $member, "
                "id: $memberId");
          }

          bool isJsInteropMember =
              (implicitJsInteropMember && member.isExternal) ||
                  expectedJsInteropMemberName != null;
          Expect.equals(
              isJsInteropMember,
              nativeData.isJsInteropMember(memberEntity),
              "Unexpected js interop member result from native data for $member, "
              "id: $memberId");
          Expect.equals(
              isJsInteropMember
                  ? expectedJsInteropMemberName ?? memberEntity.name
                  : null,
              nativeData.getJsInteropMemberName(memberEntity),
              "Unexpected js interop member name from native data for $member, "
              "id: $memberId");

          bool isNativeMember =
              implicitNativeMember || expectedNativeMemberName != null;
          Expect.equals(
              isNativeMember || isJsInteropMember,
              nativeData.isNativeMember(memberEntity),
              "Unexpected native member result from native data for $member, "
              "id: $memberId");
          Expect.equals(
              isNativeMember
                  ? expectedNativeMemberName ?? memberEntity.name
                  : (isJsInteropMember
                      ? expectedJsInteropMemberName ?? memberEntity.name
                      : null),
              nativeData.getFixedBackendName(memberEntity),
              "Unexpected fixed backend name from native data for $member, "
              "id: $memberId");

          if (expectedCreatesText != null) {
            String createsText;
            if (memberEntity is FieldEntity) {
              createsText = nativeData
                  .getNativeFieldLoadBehavior(memberEntity)
                  .typesInstantiated
                  .join(',');
            } else {
              createsText = nativeData
                  .getNativeMethodBehavior(memberEntity as FunctionEntity)
                  .typesInstantiated
                  .join(',');
            }
            Expect.equals(
                expectedCreatesText,
                createsText,
                "Unexpected create annotations from native data for $member, "
                "id: $memberId");
          }

          if (expectedReturnsText != null) {
            String returnsText;
            if (memberEntity is FieldEntity) {
              returnsText = nativeData
                  .getNativeFieldLoadBehavior(memberEntity)
                  .typesReturned
                  .join(',');
            } else {
              returnsText = nativeData
                  .getNativeMethodBehavior(memberEntity as FunctionEntity)
                  .typesReturned
                  .join(',');
            }
            Expect.equals(
                expectedReturnsText,
                returnsText,
                "Unexpected returns annotations from native data for $member, "
                "id: $memberId");
          }

          List<PragmaAnnotationData> pragmaAnnotations = frontendStrategy
              .modularStrategyForTesting
              .getPragmaAnnotationData(member);
          Set<String> pragmaNames =
              pragmaAnnotations.map((d) => d.name).toSet();
          Expect.setEquals(
              expectedPragmaNames,
              pragmaNames,
              "Unexpected pragmas from modular strategy for $member, "
              "id: $memberId");
        }

        for (ir.Library library in component.libraries) {
          if (library.importUri.isScheme('memory')) {
            String libraryId = library.importUri.path;
            LibraryEntity libraryEntity = elementMap.getLibrary(library);

            String? expectedJsInteropLibraryName =
                expectedJsInteropLibraryNames[libraryId];
            if (useIr) {
              Expect.equals(
                  expectedJsInteropLibraryName,
                  annotationData.getJsInteropLibraryName(library),
                  "Unexpected js library name from IR for $library");
            }
            Expect.equals(
                expectedJsInteropLibraryName != null,
                nativeData.isJsInteropLibrary(libraryEntity),
                "Unexpected js library result from native data for $library");
            Expect.equals(
                expectedJsInteropLibraryName,
                nativeData.getJsInteropLibraryName(libraryEntity),
                "Unexpected js library name from native data for $library");

            for (ir.Class cls in library.classes) {
              String clsId = '$libraryId::${cls.name}';
              ClassEntity classEntity = elementMap.getClass(cls);

              String? expectedNativeClassName = expectedNativeClassNames[clsId];
              if (useIr) {
                Expect.equals(
                    expectedNativeClassName,
                    annotationData.getNativeClassName(cls),
                    "Unexpected native class name from IR for $cls");
              }
              bool isNativeClass = nativeData.isNativeClass(classEntity) &&
                  !nativeData.isJsInteropClass(classEntity);
              String? nativeDataClassName;
              if (isNativeClass) {
                nativeDataClassName =
                    nativeData.getNativeTagsOfClass(classEntity).join(',');
                if (nativeData.hasNativeTagsForcedNonLeaf(classEntity)) {
                  nativeDataClassName += ',!nonleaf';
                }
              }
              Expect.equals(expectedNativeClassName != null, isNativeClass,
                  "Unexpected native class result from native data for $cls");

              Expect.equals(expectedNativeClassName, nativeDataClassName,
                  "Unexpected native class name from native data for $cls");

              String? expectedJsInteropClassName =
                  expectedJsInteropClassNames[clsId];
              if (useIr) {
                Expect.equals(
                    expectedJsInteropClassName,
                    annotationData.getJsInteropClassName(cls),
                    "Unexpected js class name from IR for $cls");
              }
              Expect.equals(
                  expectedJsInteropClassName != null,
                  nativeData.isJsInteropClass(classEntity),
                  "Unexpected js class result from native data for $cls");
              Expect.equals(
                  expectedJsInteropClassName,
                  nativeData.getJsInteropClassName(classEntity),
                  "Unexpected js class name from native data for $cls");

              bool expectedAnonymousJsInteropClass =
                  expectedAnonymousJsInteropClasses.contains(clsId);
              if (useIr) {
                Expect.equals(
                    expectedAnonymousJsInteropClass,
                    annotationData.isAnonymousJsInteropClass(cls),
                    "Unexpected js anonymous class result from IR for $cls");
              }
              Expect.equals(
                  expectedAnonymousJsInteropClass,
                  nativeData.isAnonymousJsInteropClass(classEntity),
                  "Unexpected js anonymous class result from native data for "
                  "$cls");

              for (ir.Member member in cls.members) {
                testMember(clsId, member,
                    implicitJsInteropMember:
                        nativeData.isJsInteropClass(classEntity),
                    implicitNativeMember: member is! ir.Constructor &&
                        !isTearOffLowering(member) &&
                        nativeData.isNativeClass(classEntity) &&
                        !nativeData.isJsInteropClass(classEntity));
              }
            }
            for (ir.Member member in library.members) {
              testMember(libraryId, member,
                  implicitJsInteropMember: expectedJsInteropLibraryName != null,
                  implicitNativeMember: false);
            }
          }
        }
      }

      testAll(compiler.frontendClosedWorldForTesting!.nativeData);
      if (useIr) {
        // We need to open the environment because creating annotation data
        // from IR will create K-model classes and members for all annotations
        // in the IR component, and not just the ones queried specifically for
        // JS-interop and pragma-like annotations.
        elementMap.envIsClosed = false;
        testAll(NativeData.fromIr(elementMap, annotationData));
      }
    }

    print('test annotations from K-model');
    await runTest(useIr: false);

    print('test annotations from IR');
    await runTest(useIr: true);
  });
}
