// 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 'dart:collection';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';

Constructor unnamedConstructor(Class c) =>
    c.constructors.firstWhere((c) => c.name.name == '', orElse: () => null);

/// Returns the enclosing library for reference [node].
Library getLibrary(NamedNode node) {
  for (TreeNode n = node; n != null; n = n.parent) {
    if (n is Library) return n;
  }
  return null;
}

final Pattern _syntheticTypeCharacters = new RegExp('[&^#.]');

String _escapeIdentifier(String identifier) {
  // Remove the special characters used to encode mixin application class names
  // which are legal in Kernel, but not in JavaScript.
  return identifier?.replaceAll(_syntheticTypeCharacters, r'$');
}

/// Returns the escaped name for class [node].
///
/// The caller of this function has to make sure that this name is unique in
/// the current scope.
///
/// In the current encoding, generic classes are generated in a function scope
/// which avoids name clashes of the escaped class name.
String getLocalClassName(Class node) => _escapeIdentifier(node.name);

/// Returns the escaped name for the type parameter [node].
///
/// In the current encoding, generic classes are generated in a function scope
/// which avoids name clashes of the escaped parameter name.
String getTypeParameterName(TypeParameter node) => _escapeIdentifier(node.name);

String getTopLevelName(NamedNode n) {
  if (n is Procedure) return n.name.name;
  if (n is Class) return n.name;
  if (n is Typedef) return n.name;
  if (n is Field) return n.name.name;
  return n.canonicalName?.name;
}

/// Given an annotated [node] and a [test] function, returns the first matching
/// constant valued annotation.
///
/// For example if we had the ClassDeclaration node for `FontElement`:
///
///    @js.JS('HTMLFontElement')
///    @deprecated
///    class FontElement { ... }
///
/// We could match `@deprecated` with a test function like:
///
///    (v) => v.type.name == 'Deprecated' && v.type.element.library.isDartCore
///
Expression findAnnotation(TreeNode node, bool test(Expression value)) {
  List<Expression> annotations;
  if (node is Class) {
    annotations = node.annotations;
  } else if (node is Typedef) {
    annotations = node.annotations;
  } else if (node is Procedure) {
    annotations = node.annotations;
  } else if (node is Member) {
    annotations = node.annotations;
  } else if (node is Library) {
    annotations = node.annotations;
  } else {
    return null;
  }
  return annotations.firstWhere(test, orElse: () => null);
}

bool isBuiltinAnnotation(
    Expression value, String libraryName, String expectedName) {
  if (value is ConstructorInvocation) {
    var c = value.target.enclosingClass;
    return c.name == expectedName &&
        c.enclosingLibrary.importUri.toString() == libraryName;
  }
  return false;
}

/// If [node] has annotation matching [test] and the first argument is a
/// string, this returns the string value.
///
/// Calls [findAnnotation] followed by [getNameFromAnnotation].
String getAnnotationName(NamedNode node, bool test(Expression value)) {
  return getNameFromAnnotation(findAnnotation(node, test));
}

/// If [node] is an annotation and the first argument is a string, this returns
/// the string value.
///
/// For example
///
///     class MyAnnotation {
///       final String name;
///       // ...
///       const MyAnnotation(this.name/*, ... other params ... */);
///     }
///
///     @MyAnnotation('FooBar')
///     main() { ... }
///
/// Given teh node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
String getNameFromAnnotation(ConstructorInvocation node) {
  if (node != null) {
    Expression first;
    if (node.arguments.named.isNotEmpty) {
      first = node.arguments.named
          .firstWhere((n) => n.name == 'name', orElse: () => null)
          ?.value;
    }
    if (node.arguments.positional.isNotEmpty) {
      first ??= node.arguments.positional[0];
    }
    if (first != null) {
      first = _followConstFields(first);
      if (first is StringLiteral) return first.value;
    }
  }
  return null;
}

Expression _followConstFields(Expression expr) {
  if (expr is StaticGet) {
    var target = expr.target;
    if (target is Field) {
      return _followConstFields(target.initializer);
    }
  }
  return expr;
}

/// Finds constant expressions as defined in Dart language spec 4th ed,
/// 16.1 Constants
class ConstantVisitor extends ExpressionVisitor<bool> {
  final CoreTypes coreTypes;
  ConstantVisitor(this.coreTypes);

  bool isConstant(Expression e) => e.accept(this) as bool;

  defaultExpression(node) => false;
  defaultBasicLiteral(node) => true;
  visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
  visitSymbolLiteral(node) => true;
  visitListLiteral(node) => node.isConst;
  visitMapLiteral(node) => node.isConst;
  visitStaticInvocation(node) {
    return node.isConst ||
        node.target == coreTypes.identicalProcedure &&
            node.arguments.positional.every(isConstant);
  }

  visitDirectMethodInvocation(node) {
    return node.receiver is BasicLiteral &&
        isOperatorMethodName(node.name.name) &&
        node.arguments.positional.every((p) => p is BasicLiteral);
  }

  visitMethodInvocation(node) {
    return node.receiver is BasicLiteral &&
        isOperatorMethodName(node.name.name) &&
        node.arguments.positional.every((p) => p is BasicLiteral);
  }

  visitConstructorInvocation(node) => node.isConst;
  visitStringConcatenation(node) =>
      node.expressions.every((e) => e is BasicLiteral);
  visitStaticGet(node) {
    var target = node.target;
    return target is Procedure || target is Field && target.isConst;
  }

  visitVariableGet(node) => node.variable.isConst;
  visitNot(node) {
    var operand = node.operand;
    return operand is BoolLiteral ||
        operand is DirectMethodInvocation &&
            visitDirectMethodInvocation(operand) ||
        operand is MethodInvocation && visitMethodInvocation(operand);
  }

  visitLogicalExpression(node) =>
      node.left is BoolLiteral && node.right is BoolLiteral;
  visitConditionalExpression(node) =>
      node.condition is BoolLiteral &&
      node.then is BoolLiteral &&
      node.otherwise is BoolLiteral;

  visitLet(Let node) {
    var init = node.variable.initializer;
    return (init == null || isConstant(init)) && isConstant(node.body);
  }
}

/// Returns true if [name] is an operator method that is available on primitive
/// types (`int`, `double`, `num`, `String`, `bool`).
///
/// This does not include logical operators that cannot be user-defined
/// (`!`, `&&` and `||`).
bool isOperatorMethodName(String name) {
  switch (name) {
    case '==':
    case '~':
    case '^':
    case '|':
    case '&':
    case '>>':
    case '<<':
    case '+':
    case 'unary-':
    case '-':
    case '*':
    case '/':
    case '~/':
    case '>':
    case '<':
    case '>=':
    case '<=':
    case '%':
      return true;
  }
  return false;
}

/// Returns true if this class is of the form:
/// `class C = Object with M [implements I1, I2 ...];`
///
/// A mixin alias class is a mixin application, that can also be itself used as
/// a mixin.
bool isMixinAliasClass(Class c) =>
    c.isMixinApplication && c.superclass.superclass == null;

List<Class> getSuperclasses(Class c) {
  var result = <Class>[];
  var visited = new HashSet<Class>();
  while (c != null && visited.add(c)) {
    for (var m = c.mixedInClass; m != null; m = m.mixedInClass) {
      result.add(m);
    }
    var superclass = c.superclass;
    if (superclass == null) break;
    result.add(superclass);
    c = superclass;
  }
  return result;
}

List<Class> getImmediateSuperclasses(Class c) {
  var result = <Class>[];
  var m = c.mixedInClass;
  if (m != null) result.add(m);
  var s = c.superclass;
  if (s != null) result.add(s);
  return result;
}

Expression getInvocationReceiver(InvocationExpression node) =>
    node is MethodInvocation
        ? node.receiver
        : node is DirectMethodInvocation ? node.receiver : null;

bool isInlineJS(Member e) =>
    e is Procedure &&
    e.name.name == 'JS' &&
    e.enclosingLibrary.importUri.toString() == 'dart:_foreign_helper';

// Check whether we have any covariant parameters.
// Usually we don't, so we can use the same type.
bool isCovariant(VariableDeclaration p) =>
    p.isCovariant || p.isGenericCovariantImpl;

/// Returns true iff this factory constructor just throws [UnsupportedError]/
///
/// `dart:html` has many of these.
bool isUnsupportedFactoryConstructor(Procedure node) {
  if (node.name.isPrivate && node.enclosingLibrary.importUri.scheme == 'dart') {
    var body = node.function.body;
    if (body is Block) {
      var statements = body.statements;
      if (statements.length == 1) {
        var statement = statements[0];
        if (statement is ExpressionStatement) {
          var expr = statement.expression;
          if (expr is Throw) {
            var error = expr.expression;
            if (error is ConstructorInvocation &&
                error.target.enclosingClass.name == 'UnsupportedError') {
              // HTML adds a lot of private constructors that are unreachable.
              // Skip these.
              return true;
            }
          }
        }
      }
    }
  }
  return false;
}

/// Returns the redirecting factory constructors for the enclosing class,
/// if the field [f] is storing that information, otherwise returns `null`.
Iterable<Member> getRedirectingFactories(Field f) {
  // TODO(jmesserly): this relies on implementation details in Kernel
  if (f.name.name == "_redirecting#") {
    assert(f.isStatic);
    var list = f.initializer as ListLiteral;
    return list.expressions.map((e) => (e as StaticGet).target);
  }
  return null;
}

/// Gets the real supertype of [c] and the list of [mixins] in reverse
/// application order (mixins will appear before ones they override).
///
/// This is used to ignore synthetic mixin application classes.
///
// TODO(jmesserly): consider replacing this with Kernel's mixin unrolling once
// we don't have the Analyzer backend to maintain.
Class getSuperclassAndMixins(Class c, List<Class> mixins) {
  assert(mixins.isEmpty);

  var mixedInClass = c.mixedInClass;
  if (mixedInClass != null) mixins.add(mixedInClass);

  var sc = c.superclass;
  for (; sc.isSyntheticMixinImplementation; sc = sc.superclass) {
    mixins.add(sc.mixedInClass);
  }
  return sc;
}
