// 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: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;
      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,
            {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(NativeData.fromIr(elementMap, annotationData));
      }
    }

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

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