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

// TODO(johnniwinther): Add a test that ensure that this library doesn't depend
// on the dart2js internals.
library;

// ignore: implementation_imports
import 'package:_fe_analyzer_shared/src/messages/codes.dart'
    show Message, LocatedMessage;
import 'package:_js_interop_checks/js_interop_checks.dart';
// ignore: implementation_imports
import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart';
// ignore: implementation_imports
import 'package:_js_interop_checks/src/transformations/shared_interop_transformer.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/reference_from_index.dart';
import 'package:kernel/target/changed_structure_notifier.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/type_environment.dart';

import '../options.dart';
import 'invocation_mirror.dart';
import 'transformations/modular/transform.dart' as modular_transforms;

const Iterable<String> _allowedDartSchemePaths = [
  'async',
  'html',
  'html_common',
  'indexed_db',
  'js',
  'js_util',
  'svg',
  '_native_typed_data',
  'web_audio',
  'web_gl',
];

List<Pattern> _allowedNativeTestPatterns = [
  RegExp(r'(?<!generated_)tests/web/native'),
  RegExp(r'(?<!generated_)tests/web/internal'),
  'generated_tests/web/native/native_test',
  'generated_tests/web/internal/deferred_url_test',
  'pkg/front_end/testcases/dart2js/native',
];

bool allowedNativeTest(Uri uri) {
  String path = uri.path;
  return _allowedNativeTestPatterns.any((pattern) => path.contains(pattern));
}

bool maybeEnableNative(Uri uri) {
  bool allowedDartLibrary() {
    if (!uri.isScheme('dart')) return false;
    return _allowedDartSchemePaths.contains(uri.path);
  }

  return allowedNativeTest(uri) || allowedDartLibrary();
}

/// A kernel [Target] to configure the Dart Front End for dart2js.
class Dart2jsTarget extends Target {
  @override
  final TargetFlags flags;
  @override
  final String name;

  final CompilerOptions? options;
  final bool supportsUnevaluatedConstants;
  Map<String, ir.Class>? _nativeClasses;

  Dart2jsTarget(
    this.name,
    this.flags, {
    this.options,
    this.supportsUnevaluatedConstants = true,
  });

  @override
  bool get enableNoSuchMethodForwarders => true;

  @override
  int get enabledLateLowerings => LateLowering.none;

  @override
  bool get supportsLateLoweringSentinel => true;

  @override
  bool get useStaticFieldLowering => false;

  // TODO(johnniwinther,sigmund): Remove this when js-interop handles getter
  //  calls encoded with an explicit property get or disallows getter calls.
  @override
  bool get supportsExplicitGetterCalls => false;

  @override
  int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.all;

  @override
  List<String> get extraRequiredLibraries => requiredLibraries[name]!;

  @override
  List<String> get extraIndexedLibraries => const [
    'dart:_foreign_helper',
    'dart:_interceptors',
    'dart:_js_helper',
    'dart:_js_types',
    'dart:_late_helper',
    'dart:js',
    'dart:js_interop',
    'dart:js_interop_unsafe',
    'dart:js_util',
    'dart:typed_data',
  ];

  @override
  bool mayDefineRestrictedType(Uri uri) =>
      uri.isScheme('dart') &&
      (uri.path == 'core' ||
          uri.path == 'typed_data' ||
          uri.path == '_interceptors' ||
          uri.path == '_native_typed_data' ||
          uri.path == '_js_helper');

  @override
  bool allowPlatformPrivateLibraryAccess(Uri importer, Uri imported) =>
      super.allowPlatformPrivateLibraryAccess(importer, imported) ||
      maybeEnableNative(importer) ||
      (importer.isScheme('package') &&
          (importer.path.startsWith('dart2js_runtime_metrics/') ||
              importer.path == 'js/js.dart'));

  @override
  bool enableNative(Uri uri) => maybeEnableNative(uri);

  @override
  bool get errorOnUnexactWebIntLiterals => true;

  @override
  void performModularTransformationsOnLibraries(
    ir.Component component,
    CoreTypes coreTypes,
    ClassHierarchy hierarchy,
    List<ir.Library> libraries,
    Map<String, String>? environmentDefines,
    covariant DiagnosticReporter<Message, LocatedMessage> diagnosticReporter,
    ReferenceFromIndex? referenceFromIndex, {
    void Function(String msg)? logger,
    ChangedStructureNotifier? changedStructureNotifier,
  }) {
    _nativeClasses = JsInteropChecks.getNativeClasses(component);
    final jsInteropReporter = JsInteropDiagnosticReporter(diagnosticReporter);
    var jsInteropChecks = JsInteropChecks(
      coreTypes,
      hierarchy,
      jsInteropReporter,
      _nativeClasses!,
    );
    // Process and validate first before doing anything with exports.
    for (var library in libraries) {
      jsInteropChecks.visitLibrary(library);
    }
    var sharedInteropTransformer = SharedInteropTransformer(
      TypeEnvironment(coreTypes, hierarchy),
      jsInteropReporter,
      jsInteropChecks.exportChecker,
      jsInteropChecks.extensionIndex,
    );
    var jsUtilOptimizer = JsUtilOptimizer(
      coreTypes,
      hierarchy,
      jsInteropChecks.extensionIndex,
      isDart2JS: true,
    );
    for (var library in libraries) {
      // Shared transformer has static checks, so we still visit even if there
      // are errors.
      sharedInteropTransformer.visitLibrary(library);
      // TODO (rileyporter): Merge js_util optimizations with other lowerings
      // in the single pass in `transformations/lowering.dart`.
      if (!jsInteropReporter.hasJsInteropErrors) {
        // We can't guarantee calls are well-formed, so don't transform.
        jsUtilOptimizer.visitLibrary(library);
      }
    }
    modular_transforms.transformLibraries(
      libraries,
      coreTypes,
      hierarchy,
      options,
    );
    logger?.call("Modular transformations performed");
  }

  @override
  ir.Expression instantiateInvocation(
    CoreTypes coreTypes,
    ir.Expression receiver,
    String name,
    ir.Arguments arguments,
    int offset,
    bool isSuper,
  ) {
    InvocationMirrorKind kind;
    if (name.startsWith('get:')) {
      kind = InvocationMirrorKind.getter;
      name = name.substring(4);
    } else if (name.startsWith('set:')) {
      kind = InvocationMirrorKind.setter;
      name = name.substring(4);
    } else {
      kind = InvocationMirrorKind.method;
    }
    return ir.StaticInvocation(
      coreTypes.index.getTopLevelProcedure(
        'dart:core',
        '_createInvocationMirror',
      ),
      ir.Arguments(<ir.Expression>[
        ir.StringLiteral(name)..fileOffset = offset,
        ir.ListLiteral(
          arguments.types.map<ir.Expression>((t) => ir.TypeLiteral(t)).toList(),
        ),
        ir.ListLiteral(arguments.positional)..fileOffset = offset,
        ir.MapLiteral(
            List<ir.MapLiteralEntry>.from(
              arguments.named.map((ir.NamedExpression arg) {
                return ir.MapLiteralEntry(
                  ir.StringLiteral(arg.name)..fileOffset = arg.fileOffset,
                  arg.value,
                )..fileOffset = arg.fileOffset;
              }),
            ),
            keyType: coreTypes.stringNonNullableRawType,
          )
          ..isConst = (arguments.named.isEmpty)
          ..fileOffset = arguments.fileOffset,
        ir.IntLiteral(kind.value)..fileOffset = offset,
      ]),
    )..fileOffset = offset;
  }

  @override
  ir.Expression instantiateNoSuchMethodError(
    CoreTypes coreTypes,
    ir.Expression receiver,
    String name,
    ir.Arguments arguments,
    int offset, {
    bool isMethod = false,
    bool isGetter = false,
    bool isSetter = false,
    bool isField = false,
    bool isLocalVariable = false,
    bool isDynamic = false,
    bool isSuper = false,
    bool isStatic = false,
    bool isConstructor = false,
    bool isTopLevel = false,
  }) {
    // TODO(sigmund): implement;
    return ir.InvalidExpression(null);
  }

  @override
  ConstantsBackend get constantsBackend => Dart2jsConstantsBackend(
    supportsUnevaluatedConstants: supportsUnevaluatedConstants,
  );

  @override
  DartLibrarySupport get dartLibrarySupport =>
      const Dart2jsDartLibrarySupport();
}

const implicitlyUsedLibraries = <String>[
  'dart:_foreign_helper',
  'dart:_interceptors',
  'dart:_js_helper',
  'dart:_late_helper',
  // Needed since dart:js_util methods like createDartExport use this.
  'dart:js_interop_unsafe',
  'dart:js_util',
];

// TODO(sigmund): this "extraRequiredLibraries" needs to be removed...
// compile-platform should just specify which libraries to compile instead.
const requiredLibraries = <String, List<String>>{
  'dart2js': [
    'dart:_array_flags',
    'dart:_async_status_codes',
    'dart:_dart2js_only',
    'dart:_dart2js_runtime_metrics',
    'dart:_foreign_helper',
    'dart:_http',
    'dart:_interceptors',
    'dart:_internal',
    'dart:_invocation_mirror_constants',
    'dart:_js',
    'dart:_js_annotations',
    'dart:_js_embedded_names',
    'dart:_js_helper',
    'dart:_js_names',
    'dart:_js_primitives',
    'dart:_js_shared_embedded_names',
    'dart:_js_types',
    'dart:_late_helper',
    'dart:_metadata',
    'dart:_native_typed_data',
    'dart:_recipe_syntax',
    'dart:_rti',
    'dart:async',
    'dart:collection',
    'dart:convert',
    'dart:developer',
    'dart:html',
    'dart:html_common',
    'dart:indexed_db',
    'dart:io',
    'dart:isolate',
    'dart:js',
    'dart:js_interop',
    'dart:js_interop_unsafe',
    'dart:js_util',
    'dart:math',
    'dart:svg',
    'dart:typed_data',
    'dart:web_audio',
    'dart:web_gl',
  ],
  'dart2js_server': [
    'dart:_array_flags',
    'dart:_async_status_codes',
    'dart:_dart2js_only',
    'dart:_dart2js_runtime_metrics',
    'dart:_foreign_helper',
    'dart:_http',
    'dart:_interceptors',
    'dart:_internal',
    'dart:_invocation_mirror_constants',
    'dart:_js',
    'dart:_js_annotations',
    'dart:_js_embedded_names',
    'dart:_js_helper',
    'dart:_js_names',
    'dart:_js_primitives',
    'dart:_js_shared_embedded_names',
    'dart:_js_types',
    'dart:_late_helper',
    'dart:_native_typed_data',
    'dart:_recipe_syntax',
    'dart:_rti',
    'dart:async',
    'dart:collection',
    'dart:convert',
    'dart:developer',
    'dart:io',
    'dart:isolate',
    'dart:js',
    'dart:js_interop',
    'dart:js_interop_unsafe',
    'dart:js_util',
    'dart:math',
    'dart:typed_data',
  ],
};

/// Extends the Dart2jsTarget to transform outlines to meet the requirements
/// of summaries in bazel and package-build.
class Dart2jsSummaryTarget extends Dart2jsTarget with SummaryMixin {
  @override
  final List<Uri> sources;

  @override
  final bool excludeNonSources;

  Dart2jsSummaryTarget(
    String name,
    this.sources,
    this.excludeNonSources,
    TargetFlags targetFlags,
  ) : super(name, targetFlags);
}

class Dart2jsConstantsBackend extends ConstantsBackend {
  @override
  final bool supportsUnevaluatedConstants;

  const Dart2jsConstantsBackend({required this.supportsUnevaluatedConstants});

  @override
  NumberSemantics get numberSemantics => NumberSemantics.js;
}

class Dart2jsDartLibrarySupport extends CustomizedDartLibrarySupport {
  // This is required so that `dart.library._dart2js_only` can be used as an
  // import condition. Libraries with leading underscores are otherwise
  // considered unsupported regardless of the library specification.
  const Dart2jsDartLibrarySupport() : super(supported: const {'_dart2js_only'});
}
