//===- DialectSparseTensor.cpp - 'sparse_tensor' dialect submodule --------===//
//
// 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 <optional>
#include <vector>

#include "mlir-c/AffineMap.h"
#include "mlir-c/Dialect/SparseTensor.h"
#include "mlir-c/IR.h"
#include "mlir/Bindings/Python/IRCore.h"
#include "mlir/Bindings/Python/Nanobind.h"
#include "mlir/Bindings/Python/NanobindAdaptors.h"

namespace nb = nanobind;
using namespace mlir::python::nanobind_adaptors;

namespace mlir {
namespace python {
namespace MLIR_BINDINGS_PYTHON_DOMAIN {
namespace sparse_tensor {

enum class PySparseTensorLevelFormat : std::underlying_type_t<
    MlirSparseTensorLevelFormat> {
  DENSE = MLIR_SPARSE_TENSOR_LEVEL_DENSE,
  N_OUT_OF_M = MLIR_SPARSE_TENSOR_LEVEL_N_OUT_OF_M,
  COMPRESSED = MLIR_SPARSE_TENSOR_LEVEL_COMPRESSED,
  SINGLETON = MLIR_SPARSE_TENSOR_LEVEL_SINGLETON,
  LOOSE_COMPRESSED = MLIR_SPARSE_TENSOR_LEVEL_LOOSE_COMPRESSED
};

enum class PySparseTensorLevelPropertyNondefault : std::underlying_type_t<
    MlirSparseTensorLevelPropertyNondefault> {
  NON_ORDERED = MLIR_SPARSE_PROPERTY_NON_ORDERED,
  NON_UNIQUE = MLIR_SPARSE_PROPERTY_NON_UNIQUE,
  SOA = MLIR_SPARSE_PROPERTY_SOA,
};

struct EncodingAttr : PyConcreteAttribute<EncodingAttr> {
  static constexpr IsAFunctionTy isaFunction =
      mlirAttributeIsASparseTensorEncodingAttr;
  static constexpr const char *pyClassName = "EncodingAttr";
  static inline const MlirStringRef name =
      mlirSparseTensorEncodingAttrGetName();
  using Base::Base;

  static void bindDerived(ClassTy &c) {
    c.def_static(
        "get",
        [](std::vector<MlirSparseTensorLevelType> lvlTypes,
           std::optional<PyAffineMap> dimToLvl,
           std::optional<PyAffineMap> lvlToDim, int posWidth, int crdWidth,
           std::optional<PyAttribute> explicitVal,
           std::optional<PyAttribute> implicitVal,
           DefaultingPyMlirContext context) {
          return EncodingAttr(
              context->getRef(),
              mlirSparseTensorEncodingAttrGet(
                  context.get()->get(), lvlTypes.size(), lvlTypes.data(),
                  dimToLvl ? *dimToLvl : MlirAffineMap{nullptr},
                  lvlToDim ? *lvlToDim : MlirAffineMap{nullptr}, posWidth,
                  crdWidth, explicitVal ? *explicitVal : MlirAttribute{nullptr},
                  implicitVal ? *implicitVal : MlirAttribute{nullptr}));
        },
        nb::arg("lvl_types"), nb::arg("dim_to_lvl").none(),
        nb::arg("lvl_to_dim").none(), nb::arg("pos_width"),
        nb::arg("crd_width"), nb::arg("explicit_val") = nb::none(),
        nb::arg("implicit_val") = nb::none(), nb::arg("context") = nb::none(),
        "Gets a sparse_tensor.encoding from parameters.");

    c.def_static(
        "build_level_type",
        [](PySparseTensorLevelFormat lvlFmt,
           const std::vector<PySparseTensorLevelPropertyNondefault> &properties,
           unsigned n, unsigned m) {
          std::vector<MlirSparseTensorLevelPropertyNondefault> props;
          props.reserve(properties.size());
          for (auto prop : properties) {
            props.push_back(
                static_cast<MlirSparseTensorLevelPropertyNondefault>(prop));
          }
          return mlirSparseTensorEncodingAttrBuildLvlType(
              static_cast<MlirSparseTensorLevelFormat>(lvlFmt), props.data(),
              props.size(), n, m);
        },
        nb::arg("lvl_fmt"),
        nb::arg("properties") =
            std::vector<PySparseTensorLevelPropertyNondefault>(),
        nb::arg("n") = 0, nb::arg("m") = 0,
        "Builds a sparse_tensor.encoding.level_type from parameters.");

    c.def_prop_ro("lvl_types", [](const EncodingAttr &self) {
      const int lvlRank = mlirSparseTensorEncodingGetLvlRank(self);
      std::vector<MlirSparseTensorLevelType> ret;
      ret.reserve(lvlRank);
      for (int l = 0; l < lvlRank; ++l)
        ret.push_back(mlirSparseTensorEncodingAttrGetLvlType(self, l));
      return ret;
    });

    c.def_prop_ro(
        "dim_to_lvl", [](EncodingAttr &self) -> std::optional<PyAffineMap> {
          MlirAffineMap ret = mlirSparseTensorEncodingAttrGetDimToLvl(self);
          if (mlirAffineMapIsNull(ret))
            return {};
          return PyAffineMap(self.getContext(), ret);
        });

    c.def_prop_ro(
        "lvl_to_dim", [](EncodingAttr &self) -> std::optional<PyAffineMap> {
          MlirAffineMap ret = mlirSparseTensorEncodingAttrGetLvlToDim(self);
          if (mlirAffineMapIsNull(ret))
            return {};
          return PyAffineMap(self.getContext(), ret);
        });

    c.def_prop_ro("pos_width", mlirSparseTensorEncodingAttrGetPosWidth);
    c.def_prop_ro("crd_width", mlirSparseTensorEncodingAttrGetCrdWidth);

    c.def_prop_ro("explicit_val",
                  [](EncodingAttr &self)
                      -> std::optional<nb::typed<nb::object, PyAttribute>> {
                    MlirAttribute ret =
                        mlirSparseTensorEncodingAttrGetExplicitVal(self);
                    if (mlirAttributeIsNull(ret))
                      return {};
                    return PyAttribute(self.getContext(), ret).maybeDownCast();
                  });

    c.def_prop_ro("implicit_val",
                  [](EncodingAttr &self)
                      -> std::optional<nb::typed<nb::object, PyAttribute>> {
                    MlirAttribute ret =
                        mlirSparseTensorEncodingAttrGetImplicitVal(self);
                    if (mlirAttributeIsNull(ret))
                      return {};
                    return PyAttribute(self.getContext(), ret).maybeDownCast();
                  });

    c.def_prop_ro("structured_n", [](const EncodingAttr &self) -> unsigned {
      const int lvlRank = mlirSparseTensorEncodingGetLvlRank(self);
      return mlirSparseTensorEncodingAttrGetStructuredN(
          mlirSparseTensorEncodingAttrGetLvlType(self, lvlRank - 1));
    });

    c.def_prop_ro("structured_m", [](const EncodingAttr &self) -> unsigned {
      const int lvlRank = mlirSparseTensorEncodingGetLvlRank(self);
      return mlirSparseTensorEncodingAttrGetStructuredM(
          mlirSparseTensorEncodingAttrGetLvlType(self, lvlRank - 1));
    });

    c.def_prop_ro("lvl_formats_enum", [](const EncodingAttr &self) {
      const int lvlRank = mlirSparseTensorEncodingGetLvlRank(self);
      std::vector<PySparseTensorLevelFormat> ret;
      ret.reserve(lvlRank);

      for (int l = 0; l < lvlRank; l++)
        ret.push_back(static_cast<PySparseTensorLevelFormat>(
            mlirSparseTensorEncodingAttrGetLvlFmt(self, l)));
      return ret;
    });
  }
};

static void populateDialectSparseTensorSubmodule(nb::module_ &m) {
  nb::enum_<PySparseTensorLevelFormat>(m, "LevelFormat", nb::is_arithmetic(),
                                       nb::is_flag())
      .value("dense", PySparseTensorLevelFormat::DENSE)
      .value("n_out_of_m", PySparseTensorLevelFormat::N_OUT_OF_M)
      .value("compressed", PySparseTensorLevelFormat::COMPRESSED)
      .value("singleton", PySparseTensorLevelFormat::SINGLETON)
      .value("loose_compressed", PySparseTensorLevelFormat::LOOSE_COMPRESSED);
  nb::enum_<PySparseTensorLevelPropertyNondefault>(m, "LevelProperty")
      .value("non_ordered", PySparseTensorLevelPropertyNondefault::NON_ORDERED)
      .value("non_unique", PySparseTensorLevelPropertyNondefault::NON_UNIQUE)
      .value("soa", PySparseTensorLevelPropertyNondefault::SOA);

  EncodingAttr::bind(m);
}
} // namespace sparse_tensor
} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
} // namespace python
} // namespace mlir

NB_MODULE(_mlirDialectsSparseTensor, m) {
  m.doc() = "MLIR SparseTensor dialect.";
  mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::sparse_tensor::
      populateDialectSparseTensorSubmodule(m);
}
