// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2017 Kyle Macfarlan <kyle.macfarlan@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_KLUSUPPORT_H
#define EIGEN_KLUSUPPORT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

/* TODO extract L, extract U, compute det, etc... */

/** \ingroup KLUSupport_Module
 * \brief A sparse LU factorization and solver based on KLU
 *
 * This class allows to solve for A.X = B sparse linear problems via a LU factorization
 * using the KLU library. The sparse matrix A must be squared and full rank.
 * The vectors or matrices X and B can be either dense or sparse.
 *
 * \warning The input matrix A should be in a \b compressed and \b column-major form.
 * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
 * \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class UmfPackLU, class SparseLU
 */

inline int klu_solve(klu_symbolic *Symbolic, klu_numeric *Numeric, Index ldim, Index nrhs, double B[],
                     klu_common *Common, double) {
  return klu_solve(Symbolic, Numeric, internal::convert_index<int>(ldim), internal::convert_index<int>(nrhs), B,
                   Common);
}

inline int klu_solve(klu_symbolic *Symbolic, klu_numeric *Numeric, Index ldim, Index nrhs, std::complex<double> B[],
                     klu_common *Common, std::complex<double>) {
  return klu_z_solve(Symbolic, Numeric, internal::convert_index<int>(ldim), internal::convert_index<int>(nrhs),
                     &numext::real_ref(B[0]), Common);
}

inline int klu_tsolve(klu_symbolic *Symbolic, klu_numeric *Numeric, Index ldim, Index nrhs, double B[],
                      klu_common *Common, double) {
  return klu_tsolve(Symbolic, Numeric, internal::convert_index<int>(ldim), internal::convert_index<int>(nrhs), B,
                    Common);
}

inline int klu_tsolve(klu_symbolic *Symbolic, klu_numeric *Numeric, Index ldim, Index nrhs, std::complex<double> B[],
                      klu_common *Common, std::complex<double>) {
  return klu_z_tsolve(Symbolic, Numeric, internal::convert_index<int>(ldim), internal::convert_index<int>(nrhs),
                      &numext::real_ref(B[0]), 0, Common);
}

inline klu_numeric *klu_factor(int Ap[], int Ai[], double Ax[], klu_symbolic *Symbolic, klu_common *Common, double) {
  return klu_factor(Ap, Ai, Ax, Symbolic, Common);
}

inline klu_numeric *klu_factor(int Ap[], int Ai[], std::complex<double> Ax[], klu_symbolic *Symbolic,
                               klu_common *Common, std::complex<double>) {
  return klu_z_factor(Ap, Ai, &numext::real_ref(Ax[0]), Symbolic, Common);
}

template <typename MatrixType_>
class KLU : public SparseSolverBase<KLU<MatrixType_> > {
 protected:
  typedef SparseSolverBase<KLU<MatrixType_> > Base;
  using Base::m_isInitialized;

 public:
  using Base::_solve_impl;
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef typename MatrixType::StorageIndex StorageIndex;
  typedef Matrix<Scalar, Dynamic, 1> Vector;
  typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
  typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
  typedef SparseMatrix<Scalar> LUMatrixType;
  typedef SparseMatrix<Scalar, ColMajor, int> KLUMatrixType;
  typedef Ref<const KLUMatrixType, StandardCompressedFormat> KLUMatrixRef;
  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };

 public:
  KLU() : m_dummy(0, 0), mp_matrix(m_dummy) { init(); }

  template <typename InputMatrixType>
  explicit KLU(const InputMatrixType &matrix) : mp_matrix(matrix) {
    init();
    compute(matrix);
  }

  ~KLU() {
    if (m_symbolic) klu_free_symbolic(&m_symbolic, &m_common);
    if (m_numeric) klu_free_numeric(&m_numeric, &m_common);
  }

  constexpr Index rows() const noexcept { return mp_matrix.rows(); }
  constexpr Index cols() const noexcept { return mp_matrix.cols(); }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful,
   *          \c NumericalIssue if the matrix.appears to be negative.
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "Decomposition is not initialized.");
    return m_info;
  }
#if 0  // not implemented yet
    inline const LUMatrixType& matrixL() const
    {
      if (m_extractedDataAreDirty) extractData();
      return m_l;
    }

    inline const LUMatrixType& matrixU() const
    {
      if (m_extractedDataAreDirty) extractData();
      return m_u;
    }

    inline const IntColVectorType& permutationP() const
    {
      if (m_extractedDataAreDirty) extractData();
      return m_p;
    }

    inline const IntRowVectorType& permutationQ() const
    {
      if (m_extractedDataAreDirty) extractData();
      return m_q;
    }
#endif
  /** Computes the sparse Cholesky decomposition of \a matrix
   *  Note that the matrix should be column-major, and in compressed format for best performance.
   *  \sa SparseMatrix::makeCompressed().
   */
  template <typename InputMatrixType>
  void compute(const InputMatrixType &matrix) {
    if (m_symbolic) klu_free_symbolic(&m_symbolic, &m_common);
    if (m_numeric) klu_free_numeric(&m_numeric, &m_common);
    grab(matrix.derived());
    analyzePattern_impl();
    factorize_impl();
  }

  /** Performs a symbolic decomposition on the sparsity of \a matrix.
   *
   * This function is particularly useful when solving for several problems having the same structure.
   *
   * \sa factorize(), compute()
   */
  template <typename InputMatrixType>
  void analyzePattern(const InputMatrixType &matrix) {
    if (m_symbolic) klu_free_symbolic(&m_symbolic, &m_common);
    if (m_numeric) klu_free_numeric(&m_numeric, &m_common);

    grab(matrix.derived());

    analyzePattern_impl();
  }

  /** Provides access to the control settings array used by KLU.
   *
   * See KLU documentation for details.
   */
  inline const klu_common &kluCommon() const { return m_common; }

  /** Provides access to the control settings array used by UmfPack.
   *
   * If this array contains NaN's, the default values are used.
   *
   * See KLU documentation for details.
   */
  inline klu_common &kluCommon() { return m_common; }

  /** Performs a numeric decomposition of \a matrix
   *
   * The given matrix must has the same sparsity than the matrix on which the pattern anylysis has been performed.
   *
   * \sa analyzePattern(), compute()
   */
  template <typename InputMatrixType>
  void factorize(const InputMatrixType &matrix) {
    eigen_assert(m_analysisIsOk && "KLU: you must first call analyzePattern()");
    if (m_numeric) klu_free_numeric(&m_numeric, &m_common);

    grab(matrix.derived());

    factorize_impl();
  }

  /** \internal */
  template <typename BDerived, typename XDerived>
  bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const;

#if 0  // not implemented yet
    Scalar determinant() const;

    void extractData() const;
#endif

 protected:
  void init() {
    m_info = InvalidInput;
    m_isInitialized = false;
    m_numeric = 0;
    m_symbolic = 0;
    m_extractedDataAreDirty = true;

    klu_defaults(&m_common);
  }

  void analyzePattern_impl() {
    m_info = InvalidInput;
    m_analysisIsOk = false;
    m_factorizationIsOk = false;
    m_symbolic = klu_analyze(internal::convert_index<int>(mp_matrix.rows()),
                             const_cast<StorageIndex *>(mp_matrix.outerIndexPtr()),
                             const_cast<StorageIndex *>(mp_matrix.innerIndexPtr()), &m_common);
    if (m_symbolic) {
      m_isInitialized = true;
      m_info = Success;
      m_analysisIsOk = true;
      m_extractedDataAreDirty = true;
    }
  }

  void factorize_impl() {
    m_numeric = klu_factor(const_cast<StorageIndex *>(mp_matrix.outerIndexPtr()),
                           const_cast<StorageIndex *>(mp_matrix.innerIndexPtr()),
                           const_cast<Scalar *>(mp_matrix.valuePtr()), m_symbolic, &m_common, Scalar());

    m_info = m_numeric ? Success : NumericalIssue;
    m_factorizationIsOk = m_numeric ? 1 : 0;
    m_extractedDataAreDirty = true;
  }

  template <typename MatrixDerived>
  void grab(const EigenBase<MatrixDerived> &A) {
    internal::destroy_at(&mp_matrix);
    internal::construct_at(&mp_matrix, A.derived());
  }

  void grab(const KLUMatrixRef &A) {
    if (&(A.derived()) != &mp_matrix) {
      internal::destroy_at(&mp_matrix);
      internal::construct_at(&mp_matrix, A);
    }
  }

  // cached data to reduce reallocation, etc.
#if 0  // not implemented yet
    mutable LUMatrixType m_l;
    mutable LUMatrixType m_u;
    mutable IntColVectorType m_p;
    mutable IntRowVectorType m_q;
#endif

  KLUMatrixType m_dummy;
  KLUMatrixRef mp_matrix;

  klu_numeric *m_numeric;
  klu_symbolic *m_symbolic;
  klu_common m_common;
  mutable ComputationInfo m_info;
  int m_factorizationIsOk;
  int m_analysisIsOk;
  mutable bool m_extractedDataAreDirty;

 private:
  KLU(const KLU &) {}
};

#if 0  // not implemented yet
template<typename MatrixType>
void KLU<MatrixType>::extractData() const
{
  if (m_extractedDataAreDirty)
  {
     eigen_assert(false && "KLU: extractData Not Yet Implemented");

    // get size of the data
    int lnz, unz, rows, cols, nz_udiag;
    umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar());

    // allocate data
    m_l.resize(rows,(std::min)(rows,cols));
    m_l.resizeNonZeros(lnz);

    m_u.resize((std::min)(rows,cols),cols);
    m_u.resizeNonZeros(unz);

    m_p.resize(rows);
    m_q.resize(cols);

    // extract
    umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(),
                        m_u.outerIndexPtr(), m_u.innerIndexPtr(), m_u.valuePtr(),
                        m_p.data(), m_q.data(), 0, 0, 0, m_numeric);

    m_extractedDataAreDirty = false;
  }
}

template<typename MatrixType>
typename KLU<MatrixType>::Scalar KLU<MatrixType>::determinant() const
{
  eigen_assert(false && "KLU: extractData Not Yet Implemented");
  return Scalar();
}
#endif

template <typename MatrixType>
template <typename BDerived, typename XDerived>
bool KLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const {
  Index rhsCols = b.cols();
  EIGEN_STATIC_ASSERT((XDerived::Flags & RowMajorBit) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
  eigen_assert(m_factorizationIsOk &&
               "The decomposition is not in a valid state for solving, you must first call either compute() or "
               "analyzePattern()/factorize()");

  x = b;
  int info = klu_solve(m_symbolic, m_numeric, b.rows(), rhsCols, x.const_cast_derived().data(),
                       const_cast<klu_common *>(&m_common), Scalar());

  m_info = info != 0 ? Success : NumericalIssue;
  return true;
}

}  // end namespace Eigen

#endif  // EIGEN_KLUSUPPORT_H
