// Copyright (c) 2019, 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.

library vm.transformations.ffi_use_sites;

import 'package:front_end/src/api_unstable/vm.dart'
    show
        templateFfiTypeInvalid,
        templateFfiTypeMismatch,
        templateFfiTypeUnsized,
        templateFfiNotStatic;

import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart';
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/target/targets.dart' show DiagnosticReporter;

import 'ffi.dart'
    show
        ReplacedMembers,
        NativeType,
        kNativeTypeIntStart,
        kNativeTypeIntEnd,
        FfiTransformer;

/// Checks and replaces calls to dart:ffi struct fields and methods.
void transformLibraries(
    Component component,
    CoreTypes coreTypes,
    ClassHierarchy hierarchy,
    List<Library> libraries,
    DiagnosticReporter diagnosticReporter,
    ReplacedMembers replacedFields) {
  final index = new LibraryIndex(component, ["dart:ffi"]);
  if (!index.containsLibrary("dart:ffi")) {
    // if dart:ffi is not loaded, do not do the transformation
    return;
  }
  final transformer = new _FfiUseSiteTransformer(
      index,
      coreTypes,
      hierarchy,
      diagnosticReporter,
      replacedFields.replacedGetters,
      replacedFields.replacedSetters);
  libraries.forEach(transformer.visitLibrary);
}

/// Checks and replaces calls to dart:ffi struct fields and methods.
class _FfiUseSiteTransformer extends FfiTransformer {
  final Map<Field, Procedure> replacedGetters;
  final Map<Field, Procedure> replacedSetters;

  bool isFfiLibrary;

  _FfiUseSiteTransformer(
      LibraryIndex index,
      CoreTypes coreTypes,
      ClassHierarchy hierarchy,
      DiagnosticReporter diagnosticReporter,
      this.replacedGetters,
      this.replacedSetters)
      : super(index, coreTypes, hierarchy, diagnosticReporter) {}

  @override
  TreeNode visitLibrary(Library node) {
    isFfiLibrary = node == ffiLibrary;
    return super.visitLibrary(node);
  }

  @override
  visitClass(Class node) {
    env.thisType = InterfaceType(node);
    try {
      return super.visitClass(node);
    } finally {
      env.thisType = null;
    }
  }

  @override
  visitPropertyGet(PropertyGet node) {
    super.visitPropertyGet(node);

    Procedure replacedWith = replacedGetters[node.interfaceTarget];
    if (replacedWith != null) {
      node = PropertyGet(node.receiver, replacedWith.name, replacedWith);
    }

    return node;
  }

  @override
  visitPropertySet(PropertySet node) {
    super.visitPropertySet(node);

    Procedure replacedWith = replacedSetters[node.interfaceTarget];
    if (replacedWith != null) {
      node = PropertySet(
          node.receiver, replacedWith.name, node.value, replacedWith);
    }

    return node;
  }

  @override
  visitStaticInvocation(StaticInvocation node) {
    super.visitStaticInvocation(node);

    Member target = node.target;
    try {
      if (target == fromFunctionMethod) {
        DartType nativeType =
            InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
        Expression func = node.arguments.positional[0];
        DartType dartType = func.getStaticType(env);

        _ensureIsStatic(func);
        _ensureNativeTypeValid(nativeType, node);
        _ensureNativeTypeToDartType(nativeType, dartType, node);
      }
    } catch (_FfiStaticTypeError) {}

    return node;
  }

  @override
  visitMethodInvocation(MethodInvocation node) {
    super.visitMethodInvocation(node);

    Member target = node.interfaceTarget;
    try {
      if (target == lookupFunctionMethod) {
        DartType nativeType =
            InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
        DartType dartType = node.arguments.types[1];

        _ensureNativeTypeValid(nativeType, node);
        _ensureNativeTypeToDartType(nativeType, dartType, node);
      } else if (target == asFunctionMethod) {
        if (isFfiLibrary) {
          // Library code of dart:ffi uses asFunction to implement
          // lookupFunction. Since we treat lookupFunction as well, this call
          // can be generic and still support AOT.
          return node;
        }

        DartType dartType = node.arguments.types[0];
        DartType pointerType = node.receiver.getStaticType(env);
        DartType nativeType = _pointerTypeGetTypeArg(pointerType);

        _ensureNativeTypeValid(pointerType, node);
        _ensureNativeTypeValid(nativeType, node);
        _ensureNativeTypeToDartType(nativeType, dartType, node);
      } else if (target == loadMethod) {
        // TODO(dacoharkes): should load and store permitted to be generic?
        // https://github.com/dart-lang/sdk/issues/35902
        DartType dartType = node.arguments.types[0];
        DartType pointerType = node.receiver.getStaticType(env);
        DartType nativeType = _pointerTypeGetTypeArg(pointerType);

        _ensureNativeTypeValid(pointerType, node);
        _ensureNativeTypeValid(nativeType, node);
        _ensureNativeTypeSized(nativeType, node, target.name);
        _ensureNativeTypeToDartType(nativeType, dartType, node);
      } else if (target == storeMethod) {
        // TODO(dacoharkes): should load and store permitted to be generic?
        // https://github.com/dart-lang/sdk/issues/35902
        DartType dartType = node.arguments.positional[0].getStaticType(env);
        DartType pointerType = node.receiver.getStaticType(env);
        DartType nativeType = _pointerTypeGetTypeArg(pointerType);

        _ensureNativeTypeValid(pointerType, node);
        _ensureNativeTypeValid(nativeType, node);
        _ensureNativeTypeSized(nativeType, node, target.name);
        _ensureNativeTypeToDartType(nativeType, dartType, node);
      }
    } catch (_FfiStaticTypeError) {}

    return node;
  }

  DartType _pointerTypeGetTypeArg(DartType pointerType) {
    if (pointerType is InterfaceType) {
      InterfaceType superType =
          hierarchy.getTypeAsInstanceOf(pointerType, pointerClass);
      return superType?.typeArguments[0];
    }
    return null;
  }

  void _ensureNativeTypeToDartType(
      DartType nativeType, DartType dartType, Expression node) {
    DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
    if (dartType != shouldBeDartType) {
      diagnosticReporter.report(
          templateFfiTypeMismatch.withArguments(
              dartType, shouldBeDartType, nativeType),
          node.fileOffset,
          1,
          node.location.file);
      throw _FfiStaticTypeError();
    }
  }

  void _ensureNativeTypeValid(DartType nativeType, Expression node) {
    if (!_nativeTypeValid(nativeType)) {
      diagnosticReporter.report(
          templateFfiTypeInvalid.withArguments(nativeType),
          node.fileOffset,
          1,
          node.location.file);
      throw _FfiStaticTypeError();
    }
  }

  /// The Dart type system does not enforce that NativeFunction return and
  /// parameter types are only NativeTypes, so we need to check this.
  bool _nativeTypeValid(DartType nativeType) {
    return convertNativeTypeToDartType(nativeType) != null;
  }

  void _ensureNativeTypeSized(
      DartType nativeType, Expression node, Name targetName) {
    if (!_nativeTypeSized(nativeType)) {
      diagnosticReporter.report(
          templateFfiTypeUnsized.withArguments(targetName.name, nativeType),
          node.fileOffset,
          1,
          node.location.file);
      throw _FfiStaticTypeError();
    }
  }

  /// Unsized NativeTypes do not support [sizeOf] because their size is unknown.
  /// Consequently, [allocate], [Pointer.load], [Pointer.store], and
  /// [Pointer.elementAt] are not available.
  bool _nativeTypeSized(DartType nativeType) {
    if (!(nativeType is InterfaceType)) {
      return false;
    }
    Class nativeClass = (nativeType as InterfaceType).classNode;
    if (env.isSubtypeOf(
        InterfaceType(nativeClass), InterfaceType(pointerClass))) {
      return true;
    }
    NativeType nativeType_ = getType(nativeClass);
    if (nativeType_ == null) {
      return false;
    }
    if (kNativeTypeIntStart.index <= nativeType_.index &&
        nativeType_.index <= kNativeTypeIntEnd.index) {
      return true;
    }
    if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
      return true;
    }
    if (nativeType_ == NativeType.kPointer) {
      return true;
    }
    return false;
  }

  void _ensureIsStatic(Expression node) {
    if (!_isStatic(node)) {
      diagnosticReporter.report(
          templateFfiNotStatic.withArguments(fromFunctionMethod.name.name),
          node.fileOffset,
          1,
          node.location.file);
      throw _FfiStaticTypeError();
    }
  }

  bool _isStatic(Expression node) {
    if (node is! StaticGet) return false;

    return (node as StaticGet).target is Procedure;
  }
}

/// Used internally for abnormal control flow to prevent cascading error
/// messages.
class _FfiStaticTypeError implements Exception {}
