// 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.

// @dart = 2.7

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:compiler/src/kernel/element_map_impl.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 '../helpers/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();
  new JsClass1()..jsMethod1()..jsMethod2();
  new JsClass2();
  jsMethod3();
  new NativeClass1()..nativeMethod()..nativeField;
  new NativeClass2()..nativeField;
  new 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({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;
      KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
      ir.Component component = elementMap.env.mainComponent;
      IrAnnotationData annotationData =
          frontendStrategy.irAnnotationDataForTesting;

      void testAll(NativeData nativeData) {
        void testMember(String idPrefix, ir.Member member,
            {bool implicitJsInteropMember, 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.isField) {
              createsText = nativeData
                  .getNativeFieldLoadBehavior(memberEntity)
                  .typesInstantiated
                  .join(',');
            } else {
              createsText = nativeData
                  .getNativeMethodBehavior(memberEntity)
                  .typesInstantiated
                  .join(',');
            }
            Expect.equals(
                expectedCreatesText,
                createsText,
                "Unexpected create annotations from native data for $member, "
                "id: $memberId");
          }

          if (expectedReturnsText != null) {
            String returnsText;
            if (memberEntity.isField) {
              returnsText = nativeData
                  .getNativeFieldLoadBehavior(memberEntity)
                  .typesReturned
                  .join(',');
            } else {
              returnsText = nativeData
                  .getNativeMethodBehavior(memberEntity)
                  .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 anonymousclass 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(new NativeDataImpl.fromIr(elementMap, annotationData));
      }
    }

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

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