// Copyright (c) 2018, 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/ast.dart' as ir;

import '../common.dart';
import '../elements/entities.dart';

/// Returns a textual representation of [node] that include the runtime type and
/// hash code of the node and a one line prefix of the node toString text.
String nodeToDebugString(ir.Node node, [int textLength = 40]) {
  String blockText = node.toString().replaceAll('\n', ' ');
  if (blockText.length > textLength) {
    blockText = blockText.substring(0, textLength - 3) + '...';
  }
  return '(${node.runtimeType}:${node.hashCode})${blockText}';
}

/// Comparator for the canonical order or named parameters.
// TODO(johnniwinther): Remove this when named parameters are sorted in dill.
int namedOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
  return a.name.compareTo(b.name);
}

/// Comparator for the declaration order of parameters.
int nativeOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
  return a.fileOffset.compareTo(b.fileOffset);
}

SourceSpan computeSourceSpanFromTreeNode(ir.TreeNode node) {
  // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan].
  Uri uri;
  int offset;
  while (node != null) {
    if (node.fileOffset != ir.TreeNode.noOffset) {
      offset = node.fileOffset;
      // @patch annotations have no location.
      uri = node.location?.file;
      break;
    }
    node = node.parent;
  }
  if (uri != null) {
    return new SourceSpan(uri, offset, offset + 1);
  }
  return null;
}

/// Returns the `AsyncMarker` corresponding to `node.asyncMarker`.
AsyncMarker getAsyncMarker(ir.FunctionNode node) {
  switch (node.asyncMarker) {
    case ir.AsyncMarker.Async:
      return AsyncMarker.ASYNC;
    case ir.AsyncMarker.AsyncStar:
      return AsyncMarker.ASYNC_STAR;
    case ir.AsyncMarker.Sync:
      return AsyncMarker.SYNC;
    case ir.AsyncMarker.SyncStar:
      return AsyncMarker.SYNC_STAR;
    case ir.AsyncMarker.SyncYielding:
    default:
      throw new UnsupportedError(
          "Async marker ${node.asyncMarker} is not supported.");
  }
}

/// Returns the `Variance` corresponding to `node.variance`.
Variance convertVariance(ir.TypeParameter node) {
  if (node.isLegacyCovariant) return Variance.legacyCovariant;
  switch (node.variance) {
    case ir.Variance.covariant:
      return Variance.covariant;
    case ir.Variance.contravariant:
      return Variance.contravariant;
    case ir.Variance.invariant:
      return Variance.invariant;
    default:
      throw new UnsupportedError("Variance ${node.variance} is not supported.");
  }
}

/// Returns `true` if [node] is a null literal or a null constant.
bool isNullLiteral(ir.Expression node) {
  return node is ir.NullLiteral ||
      (node is ir.ConstantExpression && node.constant is ir.NullConstant);
}

/// Kernel encodes a null-aware expression `a?.b` as
///
///     let final #1 = a in #1 == null ? null : #1.b
///
/// [getNullAwareExpression] recognizes such expressions storing the result in
/// a [NullAwareExpression] object.
///
/// [syntheticVariable] holds the synthesized `#1` variable. [expression] holds
/// the `#1.b` expression. [receiver] returns `a` expression. [parent] returns
/// the parent of the let node, i.e. the parent node of the original null-aware
/// expression. [let] returns the let node created for the encoding.
class NullAwareExpression {
  final ir.VariableDeclaration syntheticVariable;
  final ir.Expression expression;

  NullAwareExpression(this.syntheticVariable, this.expression);

  ir.Expression get receiver => syntheticVariable.initializer;

  ir.TreeNode get parent => syntheticVariable.parent.parent;

  ir.Let get let => syntheticVariable.parent;

  @override
  String toString() => let.toString();
}

NullAwareExpression getNullAwareExpression(ir.TreeNode node) {
  if (node is ir.Let) {
    ir.Expression body = node.body;
    if (node.variable.name == null &&
        node.variable.isFinal &&
        body is ir.ConditionalExpression &&
        body.condition is ir.MethodInvocation &&
        isNullLiteral(body.then)) {
      ir.MethodInvocation invocation = body.condition;
      ir.Expression receiver = invocation.receiver;
      if (invocation.name.text == '==' &&
          receiver is ir.VariableGet &&
          receiver.variable == node.variable &&
          isNullLiteral(invocation.arguments.positional.single)) {
        // We have
        //   let #t1 = e0 in #t1 == null ? null : e1
        return new NullAwareExpression(node.variable, body.otherwise);
      }
    }
  }
  return null;
}

/// Check whether [node] is immediately guarded by a
/// [ir.CheckLibraryIsLoaded], and hence the node is a deferred access.
ir.LibraryDependency getDeferredImport(ir.TreeNode node) {
  // Note: this code relies on the CFE generating the code as we expect it here.
  // If one day we optimize away redundant CheckLibraryIsLoaded instructions,
  // we'd need to derive this information directly from the CFE (See #35005),
  ir.TreeNode parent = node.parent;

  // TODO(sigmund): remove when CFE generates the correct tree (#35320). For
  // instance, it currently generates
  //
  //   let _ = check(prefix) in (prefix::field.property)
  //
  // instead of:
  //
  //   (let _ = check(prefix) in prefix::field).property
  if (node is ir.StaticGet || node is ir.ConstantExpression) {
    while (parent is ir.PropertyGet || parent is ir.MethodInvocation) {
      parent = parent.parent;
    }
  }

  if (parent is ir.Let) {
    var initializer = parent.variable.initializer;
    if (initializer is ir.CheckLibraryIsLoaded) {
      return initializer.import;
    }
  }
  return null;
}

class _FreeVariableVisitor implements ir.DartTypeVisitor<bool> {
  const _FreeVariableVisitor();

  bool visit(ir.DartType type) {
    if (type != null) return type.accept(this);
    return false;
  }

  bool visitList(List<ir.DartType> types) {
    for (ir.DartType type in types) {
      if (visit(type)) return true;
    }
    return false;
  }

  @override
  bool visitTypedefType(ir.TypedefType node) {
    return visitList(node.typeArguments);
  }

  @override
  bool visitTypeParameterType(ir.TypeParameterType node) {
    return true;
  }

  @override
  bool visitFunctionType(ir.FunctionType node) {
    if (visit(node.returnType)) return true;
    if (visitList(node.positionalParameters)) return true;
    for (ir.NamedType namedType in node.namedParameters) {
      if (visit(namedType.type)) return true;
    }
    return false;
  }

  @override
  bool visitInterfaceType(ir.InterfaceType node) {
    return visitList(node.typeArguments);
  }

  @override
  bool visitFutureOrType(ir.FutureOrType node) {
    return visit(node.typeArgument);
  }

  @override
  bool visitBottomType(ir.BottomType node) => false;

  @override
  bool visitNeverType(ir.NeverType node) => false;

  @override
  bool visitNullType(ir.NullType node) => false;

  @override
  bool visitVoidType(ir.VoidType node) => false;

  @override
  bool visitDynamicType(ir.DynamicType node) => false;

  @override
  bool visitInvalidType(ir.InvalidType node) => false;

  @override
  bool defaultDartType(ir.DartType node) {
    throw new UnsupportedError("FreeVariableVisitor.defaultTypeNode");
  }
}

/// Returns `true` if [type] contains a type variable.
///
/// All type variables (class type variables, generic method type variables,
/// and function type variables) are considered.
bool containsFreeVariables(ir.DartType type) =>
    type.accept(const _FreeVariableVisitor());

/// Returns true if [importUri] corresponds to dart:html and related libraries.
bool _isWebLibrary(Uri importUri) =>
    importUri.scheme == 'dart' &&
        (importUri.path == 'html' ||
            importUri.path == 'svg' ||
            importUri.path == 'indexed_db' ||
            importUri.path == 'web_audio' ||
            importUri.path == 'web_gl' ||
            importUri.path == 'web_sql' ||
            importUri.path == 'html_common') ||
    // Mock web library path for testing.
    importUri.path
        .contains('native_null_assertions/web_library_interfaces.dart');

bool nodeIsInWebLibrary(ir.TreeNode node) {
  if (node == null) return false;
  if (node is ir.Library) return _isWebLibrary(node.importUri);
  return nodeIsInWebLibrary(node.parent);
}

bool memberEntityIsInWebLibrary(MemberEntity entity) {
  var importUri = entity?.library?.canonicalUri;
  if (importUri == null) return false;
  return _isWebLibrary(importUri);
}

/// Returns the effective target of a super access of [target].
///
/// If [target] is a mixin super stub then the stub target is returned instead
/// of the mixin super stub. This is done to avoid unnecessary indirections
/// in super accesses.
///
/// See [ir.ProcedureStubKind.MixinSuperStub] for why mixin super stubs are
/// inserted in the first place.
ir.Member getEffectiveSuperTarget(ir.Member target) {
  if (target is ir.Procedure) {
    if (target.stubKind == ir.ProcedureStubKind.MixinSuperStub) {
      return getEffectiveSuperTarget(target.stubTarget);
    }
  }
  return target;
}
