// 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: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', 'package:js'].
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` or is the
/// internal `dart:_js_helper` library.
bool _isJSLibrary(Library library) => _isLibrary(library, [
      'package:js',
      'dart:_js_helper',
      'dart:_foreign_helper',
      'dart:_js_annotations'
    ]);

/// 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']) &&
        target.name.text == 'allowInterop';
  }
  return false;
}

bool isJsMember(Member member) {
  // TODO(vsm): If we ever use external outside the SDK for non-JS interop,
  // we're need to fix this.
  return !_isLibrary(member.enclosingLibrary, ['dart:*']) &&
      member.isExternal &&
      !isNative(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 [e] is the `JS` annotation from `package:js`.
bool isPublicJSAnnotation(Expression value) =>
    _annotationIsFromJSLibrary('JS', value);

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

/// Whether [value] is a `@JSExportName` (internal annotation used in SDK
/// instead of `@JS` from `package:js`).
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 isUndefinedAnnotation(Expression value) =>
    isBuiltinAnnotation(value, '_js_helper', '_Undefined');

/// Returns true iff the class has an `@JS(...)` annotation from `package:js`.
///
/// 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.
bool hasJSInteropAnnotation(Class c) => c.annotations.any(isPublicJSAnnotation);

/// 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 n.enclosingLibrary.annotations.any(isPublicJSAnnotation) ||
        n.annotations.any(isPublicJSAnnotation) ||
        (n.enclosingClass?.annotations.any(isPublicJSAnnotation) ?? false);
  } else if (n is Class) {
    return n.annotations.any(isPublicJSAnnotation);
  }
  return false;
}
