//===- Transform.cpp - C Interface for Transform dialect ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir-c/Dialect/Transform.h"
#include "mlir-c/Support.h"
#include "mlir/CAPI/Dialect/Transform.h"
#include "mlir/CAPI/Interfaces.h"
#include "mlir/CAPI/Registration.h"
#include "mlir/CAPI/Rewrite.h"
#include "mlir/Dialect/Transform/IR/TransformDialect.h"
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
#include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h"
#include "llvm/ADT/TypeSwitch.h"

using namespace mlir;

MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(Transform, transform,
                                      transform::TransformDialect)

//===---------------------------------------------------------------------===//
// AnyOpType
//===---------------------------------------------------------------------===//

bool mlirTypeIsATransformAnyOpType(MlirType type) {
  return isa<transform::AnyOpType>(unwrap(type));
}

MlirTypeID mlirTransformAnyOpTypeGetTypeID(void) {
  return wrap(transform::AnyOpType::getTypeID());
}

MlirType mlirTransformAnyOpTypeGet(MlirContext ctx) {
  return wrap(transform::AnyOpType::get(unwrap(ctx)));
}

MlirStringRef mlirTransformAnyOpTypeGetName(void) {
  return wrap(transform::AnyOpType::name);
}

//===---------------------------------------------------------------------===//
// AnyParamType
//===---------------------------------------------------------------------===//

bool mlirTypeIsATransformAnyParamType(MlirType type) {
  return isa<transform::AnyParamType>(unwrap(type));
}

MlirTypeID mlirTransformAnyParamTypeGetTypeID(void) {
  return wrap(transform::AnyParamType::getTypeID());
}

MlirType mlirTransformAnyParamTypeGet(MlirContext ctx) {
  return wrap(transform::AnyParamType::get(unwrap(ctx)));
}

MlirStringRef mlirTransformAnyParamTypeGetName(void) {
  return wrap(transform::AnyParamType::name);
}

//===---------------------------------------------------------------------===//
// AnyValueType
//===---------------------------------------------------------------------===//

bool mlirTypeIsATransformAnyValueType(MlirType type) {
  return isa<transform::AnyValueType>(unwrap(type));
}

MlirTypeID mlirTransformAnyValueTypeGetTypeID(void) {
  return wrap(transform::AnyValueType::getTypeID());
}

MlirType mlirTransformAnyValueTypeGet(MlirContext ctx) {
  return wrap(transform::AnyValueType::get(unwrap(ctx)));
}

MlirStringRef mlirTransformAnyValueTypeGetName(void) {
  return wrap(transform::AnyValueType::name);
}

//===---------------------------------------------------------------------===//
// OperationType
//===---------------------------------------------------------------------===//

bool mlirTypeIsATransformOperationType(MlirType type) {
  return isa<transform::OperationType>(unwrap(type));
}

MlirTypeID mlirTransformOperationTypeGetTypeID(void) {
  return wrap(transform::OperationType::getTypeID());
}

MlirType mlirTransformOperationTypeGet(MlirContext ctx,
                                       MlirStringRef operationName) {
  return wrap(
      transform::OperationType::get(unwrap(ctx), unwrap(operationName)));
}

MlirStringRef mlirTransformOperationTypeGetName(void) {
  return wrap(transform::OperationType::name);
}

MlirStringRef mlirTransformOperationTypeGetOperationName(MlirType type) {
  return wrap(cast<transform::OperationType>(unwrap(type)).getOperationName());
}

//===---------------------------------------------------------------------===//
// ParamType
//===---------------------------------------------------------------------===//

bool mlirTypeIsATransformParamType(MlirType type) {
  return isa<transform::ParamType>(unwrap(type));
}

MlirTypeID mlirTransformParamTypeGetTypeID(void) {
  return wrap(transform::ParamType::getTypeID());
}

MlirType mlirTransformParamTypeGet(MlirContext ctx, MlirType type) {
  return wrap(transform::ParamType::get(unwrap(ctx), unwrap(type)));
}

MlirStringRef mlirTransformParamTypeGetName(void) {
  return wrap(transform::ParamType::name);
}

MlirType mlirTransformParamTypeGetType(MlirType type) {
  return wrap(cast<transform::ParamType>(unwrap(type)).getType());
}

//===---------------------------------------------------------------------===//
// TransformRewriter
//===---------------------------------------------------------------------===//

/// Casts a `MlirTransformRewriter` to a `MlirRewriterBase`.
MlirRewriterBase mlirTransformRewriterAsBase(MlirTransformRewriter rewriter) {
  mlir::transform::TransformRewriter *t = unwrap(rewriter);
  mlir::RewriterBase *base = static_cast<mlir::RewriterBase *>(t);
  return wrap(base);
}

//===---------------------------------------------------------------------===//
// TransformResults
//===---------------------------------------------------------------------===//

void mlirTransformResultsSetOps(MlirTransformResults results, MlirValue result,
                                intptr_t numOps, MlirOperation *ops) {
  SmallVector<Operation *> opsVec;
  opsVec.reserve(numOps);
  for (intptr_t i = 0; i < numOps; ++i)
    opsVec.push_back(unwrap(ops[i]));
  unwrap(results)->set(cast<OpResult>(unwrap(result)), opsVec);
}

void mlirTransformResultsSetValues(MlirTransformResults results,
                                   MlirValue result, intptr_t numValues,
                                   MlirValue *values) {
  SmallVector<Value> valuesVec;
  valuesVec.reserve(numValues);
  for (intptr_t i = 0; i < numValues; ++i)
    valuesVec.push_back(unwrap(values[i]));
  unwrap(results)->setValues(cast<OpResult>(unwrap(result)), valuesVec);
}

void mlirTransformResultsSetParams(MlirTransformResults results,
                                   MlirValue result, intptr_t numParams,
                                   MlirAttribute *params) {
  SmallVector<Attribute> paramsVec;
  paramsVec.reserve(numParams);
  for (intptr_t i = 0; i < numParams; ++i)
    paramsVec.push_back(unwrap(params[i]));
  unwrap(results)->setParams(cast<OpResult>(unwrap(result)), paramsVec);
}

//===---------------------------------------------------------------------===//
// TransformState
//===---------------------------------------------------------------------===//

void mlirTransformStateForEachPayloadOp(MlirTransformState state,
                                        MlirValue value,
                                        MlirOperationCallback callback,
                                        void *userData) {
  for (Operation *op : unwrap(state)->getPayloadOps(unwrap(value)))
    callback(wrap(op), userData);
}

void mlirTransformStateForEachPayloadValue(MlirTransformState state,
                                           MlirValue value,
                                           MlirValueCallback callback,
                                           void *userData) {
  for (Value val : unwrap(state)->getPayloadValues(unwrap(value)))
    callback(wrap(val), userData);
}

void mlirTransformStateForEachParam(MlirTransformState state, MlirValue value,
                                    MlirAttributeCallback callback,
                                    void *userData) {
  for (Attribute attr : unwrap(state)->getParams(unwrap(value)))
    callback(wrap(attr), userData);
}

//===---------------------------------------------------------------------===//
// TransformOpInterface
//===---------------------------------------------------------------------===//

MlirTypeID mlirTransformOpInterfaceTypeID(void) {
  return wrap(transform::TransformOpInterface::getInterfaceID());
}

/// Fallback model for the TransformOpInterface that uses C API callbacks.
class TransformOpInterfaceFallbackModel
    : public mlir::transform::TransformOpInterface::FallbackModel<
          TransformOpInterfaceFallbackModel> {
public:
  /// Sets the callbacks that this FallbackModel will use.
  /// NB: the callbacks can only be set through this method as the
  /// RegisteredOperationName::attachInterface mechanism default-constructs
  /// the FallbackModel without being able to provide arguments.
  void setCallbacks(MlirTransformOpInterfaceCallbacks callbacks) {
    this->callbacks = callbacks;
  }

  ~TransformOpInterfaceFallbackModel() {
    if (callbacks.destruct)
      callbacks.destruct(callbacks.userData);
  }

  static TypeID getInterfaceID() {
    return transform::TransformOpInterface::getInterfaceID();
  }

  static bool classof(const mlir::transform::detail::
                          TransformOpInterfaceInterfaceTraits::Concept *op) {
    // Enable casting back to the FallbackModel from the Interface. This is
    // necessary as attachInterface(...) default-constructs the FallbackModel
    // without being able to pass in the callbacks and returns just the Concept.
    return true;
  }

  ::mlir::DiagnosedSilenceableFailure
  apply(Operation *op, ::mlir::transform::TransformRewriter &rewriter,
        ::mlir::transform::TransformResults &transformResults,
        ::mlir::transform::TransformState &state) const {
    assert(callbacks.apply && "apply callback not set");

    MlirDiagnosedSilenceableFailure status =
        callbacks.apply(wrap(op), wrap(&rewriter), wrap(&transformResults),
                        wrap(&state), callbacks.userData);

    switch (status) {
    case MlirDiagnosedSilenceableFailureSuccess:
      return DiagnosedSilenceableFailure::success();
    case MlirDiagnosedSilenceableFailureSilenceableFailure:
      // TODO: enable passing diagnostic info from C API to C++ API.
      return DiagnosedSilenceableFailure::silenceableFailure(std::move(
          *(op->emitError()
            << "TransformOpInterfaceFallbackModel: silenceable failure")
               .getUnderlyingDiagnostic()));
    case MlirDiagnosedSilenceableFailureDefiniteFailure:
      return DiagnosedSilenceableFailure::definiteFailure();
    }
    llvm_unreachable("unknown transform status");
  }

  bool allowsRepeatedHandleOperands(Operation *op) const {
    assert(callbacks.allowsRepeatedHandleOperands &&
           "allowsRepeatedHandleOperands callback not set");
    return callbacks.allowsRepeatedHandleOperands(wrap(op), callbacks.userData);
  }

private:
  MlirTransformOpInterfaceCallbacks callbacks;
};

/// Attach a TransformOpInterface FallbackModel to the given named operation.
/// The FallbackModel uses the provided callbacks to implement the interface.
void mlirTransformOpInterfaceAttachFallbackModel(
    MlirContext ctx, MlirStringRef opName,
    MlirTransformOpInterfaceCallbacks callbacks) {
  // Look up the operation definition in the context.
  std::optional<RegisteredOperationName> opInfo =
      RegisteredOperationName::lookup(unwrap(opName), unwrap(ctx));

  assert(opInfo.has_value() && "operation not found in context");

  // NB: the following default-constructs the FallbackModel _without_ being able
  // to provide arguments.
  opInfo->attachInterface<TransformOpInterfaceFallbackModel>();
  // Cast to get the underlying FallbackModel and set the callbacks.
  auto *model = cast<TransformOpInterfaceFallbackModel>(
      opInfo->getInterface<TransformOpInterfaceFallbackModel>());

  assert(model && "Failed to get TransformOpInterfaceFallbackModel");
  model->setCallbacks(callbacks);
}

//===---------------------------------------------------------------------===//
// PatternDescriptorOpInterface
//===---------------------------------------------------------------------===//

MlirTypeID mlirPatternDescriptorOpInterfaceTypeID(void) {
  return wrap(transform::PatternDescriptorOpInterface::getInterfaceID());
}

/// Fallback model for the PatternDescriptorOpInterface that uses C API
/// callbacks.
class PatternDescriptorOpInterfaceFallbackModel
    : public mlir::transform::PatternDescriptorOpInterface::FallbackModel<
          PatternDescriptorOpInterfaceFallbackModel> {
public:
  /// Sets the callbacks that this FallbackModel will use.
  /// NB: the callbacks can only be set through this method as the
  /// RegisteredOperationName::attachInterface mechanism default-constructs
  /// the FallbackModel without being able to provide arguments.
  void setCallbacks(MlirPatternDescriptorOpInterfaceCallbacks callbacks) {
    this->callbacks = callbacks;
  }

  ~PatternDescriptorOpInterfaceFallbackModel() {
    if (callbacks.destruct)
      callbacks.destruct(callbacks.userData);
  }

  static TypeID getInterfaceID() {
    return transform::PatternDescriptorOpInterface::getInterfaceID();
  }

  static bool
  classof(const mlir::transform::detail::
              PatternDescriptorOpInterfaceInterfaceTraits::Concept *op) {
    // Enable casting back to the FallbackModel from the Interface. This is
    // necessary as attachInterface(...) default-constructs the FallbackModel
    // without being able to pass in the callbacks and returns just the Concept.
    return true;
  }

  void populatePatterns(Operation *op, RewritePatternSet &patterns) const {
    assert(callbacks.populatePatterns && "populatePatterns callback not set");
    callbacks.populatePatterns(wrap(op), wrap(&patterns), callbacks.userData);
  }

  void populatePatternsWithState(Operation *op, RewritePatternSet &patterns,
                                 transform::TransformState &state) const {
    if (callbacks.populatePatternsWithState) {
      callbacks.populatePatternsWithState(wrap(op), wrap(&patterns),
                                          wrap(&state), callbacks.userData);
    } else {
      // Default implementation: call populatePatterns without state.
      populatePatterns(op, patterns);
    }
  }

private:
  MlirPatternDescriptorOpInterfaceCallbacks callbacks;
};

/// Attach a PatternDescriptorOpInterface FallbackModel to the given named
/// operation. The FallbackModel uses the provided callbacks to implement the
/// interface.
void mlirPatternDescriptorOpInterfaceAttachFallbackModel(
    MlirContext ctx, MlirStringRef opName,
    MlirPatternDescriptorOpInterfaceCallbacks callbacks) {
  // Look up the operation definition in the context.
  std::optional<RegisteredOperationName> opInfo =
      RegisteredOperationName::lookup(unwrap(opName), unwrap(ctx));

  assert(opInfo.has_value() && "operation not found in context");

  // NB: the following default-constructs the FallbackModel _without_ being able
  // to provide arguments.
  opInfo->attachInterface<PatternDescriptorOpInterfaceFallbackModel>();
  // Cast to get the underlying FallbackModel and set the callbacks.
  auto *model = cast<PatternDescriptorOpInterfaceFallbackModel>(
      opInfo->getInterface<PatternDescriptorOpInterfaceFallbackModel>());

  assert(model && "Failed to get PatternDescriptorOpInterfaceFallbackModel");
  model->setCallbacks(callbacks);
}

//===---------------------------------------------------------------------===//
// MemoryEffectsOpInterface helpers
//===---------------------------------------------------------------------===//

static void invokeMemoryEffectInstancesCallback(
    SmallVectorImpl<MemoryEffects::EffectInstance> &effects,
    MlirMemoryEffectInstancesCallback callback, void *userData) {
  SmallVector<MlirMemoryEffectInstance> wrappedEffects;
  wrappedEffects.reserve(effects.size());
  for (MemoryEffects::EffectInstance &effect : effects)
    wrappedEffects.push_back(wrap(&effect));
  callback(wrappedEffects.size(), wrappedEffects.data(), userData);
}

/// Set the effect for the operands to only read the transform handles.
void mlirTransformOnlyReadsHandle(MlirOpOperand *operands, intptr_t numOperands,
                                  MlirMemoryEffectInstancesCallback callback,
                                  void *userData) {
  MutableArrayRef<OpOperand> operandArray;
  if (numOperands != 0)
    operandArray = MutableArrayRef<OpOperand>(unwrap(*operands), numOperands);
  SmallVector<MemoryEffects::EffectInstance> effects;
  transform::onlyReadsHandle(operandArray, effects);
  invokeMemoryEffectInstancesCallback(effects, callback, userData);
}

/// Set the effect for the operands to consuming the transform handles.
void mlirTransformConsumesHandle(MlirOpOperand *operands, intptr_t numOperands,
                                 MlirMemoryEffectInstancesCallback callback,
                                 void *userData) {
  MutableArrayRef<OpOperand> operandArray;
  if (numOperands != 0)
    operandArray = MutableArrayRef<OpOperand>(unwrap(*operands), numOperands);
  SmallVector<MemoryEffects::EffectInstance> effects;
  transform::consumesHandle(operandArray, effects);
  invokeMemoryEffectInstancesCallback(effects, callback, userData);
}

/// Set the effect for the results to that they produce transform handles.
void mlirTransformProducesHandle(MlirValue *results, intptr_t numResults,
                                 MlirMemoryEffectInstancesCallback callback,
                                 void *userData) {
  // NB: calling `producesHandle()` `numResults` as we cannot cast array of
  // `OpResult`s to a single `ResultRange` (and neither is `ResultRange` exposed
  // to Python). `producesHandle` iterates over the given `ResultRange` anyway.
  SmallVector<MemoryEffects::EffectInstance> effects;
  for (intptr_t i = 0; i < numResults; ++i) {
    auto opResult = cast<OpResult>(unwrap(results[i]));
    transform::producesHandle(ResultRange(opResult), effects);
  }
  invokeMemoryEffectInstancesCallback(effects, callback, userData);
}

/// Set the effect of potentially modifying payload IR.
void mlirTransformModifiesPayload(MlirMemoryEffectInstancesCallback callback,
                                  void *userData) {
  SmallVector<MemoryEffects::EffectInstance> effects;
  transform::modifiesPayload(effects);
  invokeMemoryEffectInstancesCallback(effects, callback, userData);
}

/// Set the effect of potentially reading payload IR.
void mlirTransformOnlyReadsPayload(MlirMemoryEffectInstancesCallback callback,
                                   void *userData) {
  SmallVector<MemoryEffects::EffectInstance> effects;
  transform::onlyReadsPayload(effects);
  invokeMemoryEffectInstancesCallback(effects, callback, userData);
}
