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

import 'package:_js_interop_checks/src/js_interop.dart';
import 'package:kernel/kernel.dart';

import 'kernel_helpers.dart';

/// Returns true if [library] is one of the [candidates].
/// The latter should be a list, e.g.,: ['dart:js', 'dart:_js_annotations'].
bool _isLibrary(Library library, List<String> candidates) {
  var uri = library.importUri;
  var scheme = uri.scheme;
  var path = uri.pathSegments[0];
  for (var candidate in candidates) {
    var pair = candidate.split(':');
    if (scheme == pair[0] && (path == pair[1] || pair[1] == '*')) {
      return true;
    }
  }
  return false;
}

/// Returns true if [library] represents any library from `package:js`,
/// `dart:_foreign_helper`, `dart:_js_annotations`, or `dart:_js_helper`, or
/// `dart:js_interop`.
bool _isJSLibrary(Library library) => _isLibrary(library, [
  // While the annotations no longer live in `package:js`, this is needed to
  // support older versions of the package.
  'package:js',
  'dart:_foreign_helper',
  'dart:_js_annotations',
  'dart:_js_helper',
  // This is to allow `dart:js_interop`'s `@JS` to work with
  // `@staticInterop`.
  'dart:js_interop',
]);

/// Whether [node] is a direct call to `allowInterop`.
bool isAllowInterop(Expression node) {
  if (node is StaticInvocation) {
    var target = node.target;
    return _isLibrary(target.enclosingLibrary, ['dart:js_util']) &&
        target.name.text == 'allowInterop';
  }
  return false;
}

bool isJsMember(Member member) {
  return member.isExternal &&
      !_isLibrary(member.enclosingLibrary, ['dart:*']) &&
      !isNative(member) &&
      // Non-JS interop external members might exist e.g. the ones generated by
      // Angular, so we should check to see that this member actually uses JS
      // interop.
      usesJSInterop(member);
}

bool _annotationIsFromJSLibrary(String expectedName, Expression value) {
  var c = getAnnotationClass(value);
  return c != null &&
      c.name == expectedName &&
      _isJSLibrary(c.enclosingLibrary);
}

/// Whether [value] is a `@rest` annotation (to be used on function parameters
/// to have them compiled as `...` rest params in ES6 outputs).
bool isJsRestAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('_Rest', value);

// TODO(jmesserly): Move JsPeerInterface to package:js (see issue #135).
// TODO(jacobr): The 'JS' annotation is the new, publicly accessible one.
// The 'JsName' annotation is the old one using internally by dart2js and
// html libraries.  These two concepts will probably merge eventually.
bool isJSAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('JS', value) || isJSName(value);

/// Returns [true] if [value] is the `JS` annotation from
/// `package:js`, `dart:_js_annotations`, or `dart:js_interop`.
bool isJSInteropAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('JS', value);

bool _isJSAnonymousAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('_Anonymous', value);

bool _isStaticInteropAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('_StaticInterop', value);

/// Whether [value] is a `@JSExportName` (internal annotation used in SDK
/// instead of `@JS` from `dart:_js_annotations`).
bool isJSExportNameAnnotation(Expression value) =>
    isBuiltinAnnotation(value, '_foreign_helper', 'JSExportName');

/// Whether [i] is a `spread` invocation (to be used on function arguments
/// to have them compiled as `...` spread args in ES6 outputs).
bool isJSSpreadInvocation(Procedure target) =>
    target.name.text == 'spread' && _isJSLibrary(target.enclosingLibrary);

bool isJSName(Expression value) =>
    isBuiltinAnnotation(value, '_js_helper', 'JSName');

bool isJsPeerInterface(Expression value) =>
    isBuiltinAnnotation(value, '_js_helper', 'JsPeerInterface');

bool isNativeAnnotation(Expression value) =>
    isBuiltinAnnotation(value, '_js_helper', 'Native');

bool isJSAnonymousType(Class namedClass) {
  var hasJSInterop = hasJSInteropAnnotation(namedClass);
  var isAnonymous =
      findAnnotation(namedClass, _isJSAnonymousAnnotation) != null;
  return hasJSInterop && isAnonymous;
}

bool isStaticInteropType(Class namedClass) {
  var hasJSInterop = hasJSInteropAnnotation(namedClass);
  var isStaticInterop =
      findAnnotation(namedClass, _isStaticInteropAnnotation) != null;
  return hasJSInterop && isStaticInterop;
}

bool isUndefinedAnnotation(Expression value) =>
    isBuiltinAnnotation(value, '_js_helper', '_Undefined');

/// Returns true iff the annotatable has an `@JS(...)` annotation from
/// `package:js`, `dart:_js_annotations`, or `dart:js_interop`.
///
/// Note: usually [usesJSInterop] should be used instead of this.
//
// TODO(jmesserly): I think almost all uses of this should be replaced with
// [usesJSInterop], which also checks that the library is marked with `@JS`.
//
// Right now we have inconsistencies: sometimes we'll respect `@JS` on the
// class itself, other places we require it on the library. Also members are
// inconsistent: sometimes they need to have `@JS` on them, other times they
// need to be `external` in an `@JS` class.
//
// TODO(srujzs): We should replace many of these helpers with the ones defined
// in pkg:_js_interop_checks.
bool hasJSInteropAnnotation(Annotatable a) =>
    a.annotations.any(isJSInteropAnnotation);

/// Returns true iff this element is a JS interop member.
///
/// JS annotations are required explicitly on classes. Other elements, such as
/// class members and top-level functions/accessors, should be marked `external`
/// and should have directly or indirectly a `JS` annotation. It is sufficient
/// if the annotation is in the procedure itself or an enclosing element like
/// the class or library.
bool usesJSInterop(NamedNode n) {
  if (n is Member && n.isExternal) {
    return hasJSInteropAnnotation(n) ||
        (n.enclosingClass == null
            ? hasJSInteropAnnotation(n.enclosingLibrary)
            : hasJSInteropAnnotation(n.enclosingClass!));
  } else if (n is Class) {
    return n.annotations.any(isJSInteropAnnotation);
  }
  return false;
}

/// Returns `true` when [member] is a JavaScript interop member using the
/// package:js style of interop.
///
/// Will return `false` when the newer static interop style is used or when
/// [member] is not a JavaScript interop member at all.
bool isNonStaticJsInterop(Member member) {
  return member.isExternal &&
      !member.isExtensionMember &&
      !member.isExtensionTypeMember &&
      _usesNonStaticInteropAnnotation(member);
}

/// Returns `true` when [member] is a JavaScript interop member using the
/// package:js style of interop annotation.
///
/// This does not mean [member] has the annotation directly because it can
/// be applied on the class or the library level.
///
/// Will return `false` when the newer static interop style annotation is
/// found or when [member] is not a JavaScript interop member at all.
bool _usesNonStaticInteropAnnotation(Member member) {
  var enclosingClass = member.enclosingClass;
  if (enclosingClass != null) {
    return hasPackageJSAnnotation(enclosingClass) &&
        !hasStaticInteropAnnotation(enclosingClass);
  }
  return hasPackageJSAnnotation(member) ||
      hasPackageJSAnnotation(member.enclosingLibrary);
}
