// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
//
// 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_SKYLINE_STORAGE_H
#define EIGEN_SKYLINE_STORAGE_H

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

namespace Eigen {

/** Stores a skyline set of values in three structures :
 * The diagonal elements
 * The upper elements
 * The lower elements
 *
 */
template <typename Scalar>
class SkylineStorage {
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef SparseIndex Index;

 public:
  SkylineStorage()
      : m_diag(0),
        m_lower(0),
        m_upper(0),
        m_lowerProfile(0),
        m_upperProfile(0),
        m_diagSize(0),
        m_upperSize(0),
        m_lowerSize(0),
        m_upperProfileSize(0),
        m_lowerProfileSize(0),
        m_allocatedSize(0) {}

  SkylineStorage(const SkylineStorage& other)
      : m_diag(0),
        m_lower(0),
        m_upper(0),
        m_lowerProfile(0),
        m_upperProfile(0),
        m_diagSize(0),
        m_upperSize(0),
        m_lowerSize(0),
        m_upperProfileSize(0),
        m_lowerProfileSize(0),
        m_allocatedSize(0) {
    *this = other;
  }

  SkylineStorage& operator=(const SkylineStorage& other) {
    resize(other.diagSize(), other.m_upperProfileSize, other.m_lowerProfileSize, other.upperSize(), other.lowerSize());
    memcpy(m_diag, other.m_diag, m_diagSize * sizeof(Scalar));
    memcpy(m_upper, other.m_upper, other.upperSize() * sizeof(Scalar));
    memcpy(m_lower, other.m_lower, other.lowerSize() * sizeof(Scalar));
    memcpy(m_upperProfile, other.m_upperProfile, m_upperProfileSize * sizeof(Index));
    memcpy(m_lowerProfile, other.m_lowerProfile, m_lowerProfileSize * sizeof(Index));
    return *this;
  }

  void swap(SkylineStorage& other) {
    std::swap(m_diag, other.m_diag);
    std::swap(m_upper, other.m_upper);
    std::swap(m_lower, other.m_lower);
    std::swap(m_upperProfile, other.m_upperProfile);
    std::swap(m_lowerProfile, other.m_lowerProfile);
    std::swap(m_diagSize, other.m_diagSize);
    std::swap(m_upperSize, other.m_upperSize);
    std::swap(m_lowerSize, other.m_lowerSize);
    std::swap(m_allocatedSize, other.m_allocatedSize);
  }

  ~SkylineStorage() {
    delete[] m_diag;
    delete[] m_upper;
    if (m_upper != m_lower) delete[] m_lower;
    delete[] m_upperProfile;
    delete[] m_lowerProfile;
  }

  void reserve(Index size, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize) {
    Index newAllocatedSize = size + upperSize + lowerSize;
    if (newAllocatedSize > m_allocatedSize) reallocate(size, upperProfileSize, lowerProfileSize, upperSize, lowerSize);
  }

  void squeeze() {
    if (m_allocatedSize > m_diagSize + m_upperSize + m_lowerSize)
      reallocate(m_diagSize, m_upperProfileSize, m_lowerProfileSize, m_upperSize, m_lowerSize);
  }

  void resize(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize,
              float reserveSizeFactor = 0) {
    if (m_allocatedSize < diagSize + upperSize + lowerSize)
      reallocate(diagSize, upperProfileSize, lowerProfileSize, upperSize + Index(reserveSizeFactor * upperSize),
                 lowerSize + Index(reserveSizeFactor * lowerSize));
    m_diagSize = diagSize;
    m_upperSize = upperSize;
    m_lowerSize = lowerSize;
    m_upperProfileSize = upperProfileSize;
    m_lowerProfileSize = lowerProfileSize;
  }

  inline Index diagSize() const { return m_diagSize; }

  inline Index upperSize() const { return m_upperSize; }

  inline Index lowerSize() const { return m_lowerSize; }

  inline Index upperProfileSize() const { return m_upperProfileSize; }

  inline Index lowerProfileSize() const { return m_lowerProfileSize; }

  inline Index allocatedSize() const { return m_allocatedSize; }

  inline void clear() { m_diagSize = 0; }

  inline Scalar& diag(Index i) { return m_diag[i]; }

  inline const Scalar& diag(Index i) const { return m_diag[i]; }

  inline Scalar& upper(Index i) { return m_upper[i]; }

  inline const Scalar& upper(Index i) const { return m_upper[i]; }

  inline Scalar& lower(Index i) { return m_lower[i]; }

  inline const Scalar& lower(Index i) const { return m_lower[i]; }

  inline Index& upperProfile(Index i) { return m_upperProfile[i]; }

  inline const Index& upperProfile(Index i) const { return m_upperProfile[i]; }

  inline Index& lowerProfile(Index i) { return m_lowerProfile[i]; }

  inline const Index& lowerProfile(Index i) const { return m_lowerProfile[i]; }

  static SkylineStorage Map(Index* upperProfile, Index* lowerProfile, Scalar* diag, Scalar* upper, Scalar* lower,
                            Index size, Index upperSize, Index lowerSize) {
    SkylineStorage res;
    res.m_upperProfile = upperProfile;
    res.m_lowerProfile = lowerProfile;
    res.m_diag = diag;
    res.m_upper = upper;
    res.m_lower = lower;
    res.m_allocatedSize = res.m_diagSize = size;
    res.m_upperSize = upperSize;
    res.m_lowerSize = lowerSize;
    return res;
  }

  inline void reset() {
    std::fill_n(m_diag, m_diagSize, Scalar(0));
    std::fill_n(m_upper, m_upperSize, Scalar(0));
    std::fill_n(m_lower, m_lowerSize, Scalar(0));
    std::fill_n(m_upperProfile, m_diagSize, Index(0));
    std::fill_n(m_lowerProfile, m_diagSize, Index(0));
  }

  void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) {
    // TODO
  }

 protected:
  inline void reallocate(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize,
                         Index lowerSize) {
    Scalar* diag = new Scalar[diagSize];
    Scalar* upper = new Scalar[upperSize];
    Scalar* lower = new Scalar[lowerSize];
    Index* upperProfile = new Index[upperProfileSize];
    Index* lowerProfile = new Index[lowerProfileSize];

    Index copyDiagSize = (std::min)(diagSize, m_diagSize);
    Index copyUpperSize = (std::min)(upperSize, m_upperSize);
    Index copyLowerSize = (std::min)(lowerSize, m_lowerSize);
    Index copyUpperProfileSize = (std::min)(upperProfileSize, m_upperProfileSize);
    Index copyLowerProfileSize = (std::min)(lowerProfileSize, m_lowerProfileSize);

    // copy
    memcpy(diag, m_diag, copyDiagSize * sizeof(Scalar));
    memcpy(upper, m_upper, copyUpperSize * sizeof(Scalar));
    memcpy(lower, m_lower, copyLowerSize * sizeof(Scalar));
    memcpy(upperProfile, m_upperProfile, copyUpperProfileSize * sizeof(Index));
    memcpy(lowerProfile, m_lowerProfile, copyLowerProfileSize * sizeof(Index));

    // delete old stuff
    delete[] m_diag;
    delete[] m_upper;
    delete[] m_lower;
    delete[] m_upperProfile;
    delete[] m_lowerProfile;
    m_diag = diag;
    m_upper = upper;
    m_lower = lower;
    m_upperProfile = upperProfile;
    m_lowerProfile = lowerProfile;
    m_allocatedSize = diagSize + upperSize + lowerSize;
    m_upperSize = upperSize;
    m_lowerSize = lowerSize;
  }

 public:
  Scalar* m_diag;
  Scalar* m_upper;
  Scalar* m_lower;
  Index* m_upperProfile;
  Index* m_lowerProfile;
  Index m_diagSize;
  Index m_upperSize;
  Index m_lowerSize;
  Index m_upperProfileSize;
  Index m_lowerProfileSize;
  Index m_allocatedSize;
};

}  // end namespace Eigen

#endif  // EIGEN_SKYLINE_STORAGE_H
