// Copyright (c) 2020, 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 'package:kernel/util/graph.dart' as kernel_graph;

/// Returns true iff the node has an `@JS(...)` annotation from `package:js` or
/// from the internal `dart:_js_annotations`.
bool hasJSInteropAnnotation(Annotatable a) =>
    a.annotations.any(_isPublicJSAnnotation);

/// Returns true iff the node has an `@anonymous` annotation from `package:js`
/// or from the internal `dart:_js_annotations`.
bool hasAnonymousAnnotation(Annotatable a) =>
    a.annotations.any(_isAnonymousAnnotation);

/// Returns true iff the node has an `@staticInterop` annotation from
/// `package:js` or from the internal `dart:_js_annotations`.
bool hasStaticInteropAnnotation(Annotatable a) =>
    a.annotations.any(_isStaticInteropAnnotation);

/// Returns true iff the node has an `@trustTypes` annotation from
/// `package:js` or from the internal `dart:_js_annotations`.
bool hasTrustTypesAnnotation(Annotatable a) =>
    a.annotations.any(_isTrustTypesAnnotation);

/// If [a] has a `@JS('...')` annotation, returns the value inside the
/// parentheses.
///
/// If there is none or the class does not have a `@JS()` annotation, returns
/// an empty String.
String getJSName(Annotatable a) {
  String jsClass = '';
  for (var annotation in a.annotations) {
    if (_isPublicJSAnnotation(annotation)) {
      var jsClasses = _stringAnnotationValues(annotation);
      if (jsClasses.isNotEmpty) {
        jsClass = jsClasses[0];
      }
    }
  }
  return jsClass;
}

/// If [a] has a `@Native('...')` annotation, returns the values inside the
/// parentheses.
///
/// If there are none or the class does not have a `@Native()` annotation,
/// returns an empty list. Unlike `@JS()`, the string within `@Native()` is
/// allowed to contain several classes separated by a `,`.
List<String> getNativeNames(Annotatable a) {
  List<String> nativeClasses = [];
  for (var annotation in a.annotations) {
    if (_isNativeAnnotation(annotation)) {
      nativeClasses.addAll(_stringAnnotationValues(annotation));
    }
  }
  return nativeClasses;
}

final _packageJs = Uri.parse('package:js/js.dart');
final _internalJs = Uri.parse('dart:_js_annotations');
final _jsHelper = Uri.parse('dart:_js_helper');

bool _isAnyInteropUri(Uri uri) => uri == _packageJs || uri == _internalJs;

/// Returns true if [value] is the interop annotation whose class is
/// [annotationClassName] from `package:js` or from `dart:_js_annotations`.
bool _isInteropAnnotation(Expression value, String annotationClassName) {
  var c = _annotationClass(value);
  return c != null &&
      c.name == annotationClassName &&
      _isAnyInteropUri(c.enclosingLibrary.importUri);
}

bool _isPublicJSAnnotation(Expression value) =>
    _isInteropAnnotation(value, 'JS');

bool _isAnonymousAnnotation(Expression value) =>
    _isInteropAnnotation(value, '_Anonymous');

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

bool _isTrustTypesAnnotation(Expression value) =>
    _isInteropAnnotation(value, '_TrustTypes');

/// Returns true if [value] is the `Native` annotation from `dart:_js_helper`.
bool _isNativeAnnotation(Expression value) {
  var c = _annotationClass(value);
  return c != null &&
      c.name == 'Native' &&
      c.enclosingLibrary.importUri == _jsHelper;
}

/// Returns the class of the instance referred to by metadata annotation [node].
///
/// For example:
///
/// - `@JS()` would return the "JS" class in "package:js".
/// - `@anonymous` would return the "_Anonymous" class in "package:js".
/// - `@staticInterop` would return the "_StaticInterop" class in "package:js".
/// - `@Native` would return the "Native" class in "dart:_js_helper".
///
/// This function works regardless of whether the CFE is evaluating constants,
/// or whether the constant is a field reference (such as "anonymous" above).
Class? _annotationClass(Expression node) {
  if (node is ConstantExpression) {
    var constant = node.constant;
    if (constant is InstanceConstant) return constant.classNode;
  } else if (node is ConstructorInvocation) {
    return node.target.enclosingClass;
  } else if (node is StaticGet) {
    var type = node.target.getterType;
    if (type is InterfaceType) return type.classNode;
  }
  return null;
}

/// Returns the string values inside of a metadata annotation [node].
///
/// For example:
/// - `@JS('Foo')` would return ['Foo'].
/// - `@Native('Foo,Bar')` would return ['Foo', 'Bar'].
///
/// [node] is expected to be an annotation with either StringConstants or
/// StringLiterals that can be made up of multiple values. If there are none,
/// this method returns an empty list. This method throws an assertion if there
/// are multiple arguments or a named arg in the annotation.
List<String> _stringAnnotationValues(Expression node) {
  List<String> values = [];
  if (node is ConstantExpression) {
    var constant = node.constant;
    if (constant is InstanceConstant) {
      var argLength = constant.fieldValues.values.length;
      if (argLength == 1) {
        var value = constant.fieldValues.values.elementAt(0);
        if (value is StringConstant) values.addAll(value.value.split(','));
      } else if (argLength > 1) {
        throw new ArgumentError('Method expects annotation with at most one '
            'positional argument: $node.');
      }
    }
  } else if (node is ConstructorInvocation) {
    var argLength = node.arguments.positional.length;
    if (argLength > 1 || node.arguments.named.isNotEmpty) {
      throw new ArgumentError('Method expects annotation with at most one '
          'positional argument: $node.');
    } else if (argLength == 1) {
      var value = node.arguments.positional[0];
      if (value is StringLiteral) values.addAll(value.value.split(','));
    }
  }
  return values;
}

/// Returns the [Library] within [component] matching the specified
/// [interopUri] or [null].
Library? _findJsInteropLibrary(Component component, Uri interopUri) {
  for (Library lib in component.libraries) {
    for (LibraryDependency dependency in lib.dependencies) {
      Library targetLibrary = dependency.targetLibrary;
      if (targetLibrary.importUri == interopUri) {
        return targetLibrary;
      }
    }
  }
  return null;
}

/// Calculates the libraries in [component] that transitively import a given js
/// interop library.
///
/// Returns null if the given js interop library is not imported.
/// NOTE: This function was based off of
/// `calculateTransitiveImportsOfDartFfiIfUsed` in
/// pkg/vm/lib/transformations/ffi/common.dart.
List<Library>? calculateTransitiveImportsOfJsInteropIfUsed(
    Component component, Uri interopUri) {
  // Check for the presence of [jsInteropLibrary] as a dependency of any of the
  // libraries in [component]. We use this to bypass the expensive
  // [calculateTransitiveDependenciesOf] call for cases where js interop is
  // not used, otherwise we could just use the index of the library instead.
  Library? jsInteropLibrary = _findJsInteropLibrary(component, interopUri);
  if (jsInteropLibrary == null) return null;

  kernel_graph.LibraryGraph graph =
      new kernel_graph.LibraryGraph(component.libraries);
  Set<Library> result =
      kernel_graph.calculateTransitiveDependenciesOf(graph, {jsInteropLibrary});
  return result.toList();
}
