/* ----------------------------------------------------------------------- *//**
 *
 * @file DynamicStruct_impl.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_POSTGRES_DYNAMICSTRUCT_IMPL_HPP
#define MADLIB_POSTGRES_DYNAMICSTRUCT_IMPL_HPP

namespace madlib {

namespace dbal {

/**
 * @brief Meta function for mapping types to the dynamic-struct mapped type
 *
 * @tparam T Desired type that is to be stored in the dynamic struct
 * @tparam IsMutable Indicator if the dynamic struct is mutable
 */
template <class T, bool IsMutable>
struct DynamicStructType {
    typedef Ref<T, IsMutable> type;
};

template <bool IsMutable>
struct DynamicStructType<eigen_integration::ColumnVector, IsMutable> {
    typedef eigen_integration::HandleMap<
        typename boost::mpl::if_c<IsMutable,
            eigen_integration::ColumnVector,
            const eigen_integration::ColumnVector>::type,
        TransparentHandle<double, IsMutable> > type;
};

template <bool IsMutable>
struct DynamicStructType<eigen_integration::IntegerVector, IsMutable> {
    typedef eigen_integration::HandleMap<
        typename boost::mpl::if_c<IsMutable,
            eigen_integration::IntegerVector,
            const eigen_integration::IntegerVector>::type,
        TransparentHandle<int, IsMutable> > type;
};

template <bool IsMutable>
struct DynamicStructType<eigen_integration::Matrix, IsMutable> {
    typedef eigen_integration::HandleMap<
        typename boost::mpl::if_c<IsMutable,
            eigen_integration::Matrix,
            const eigen_integration::Matrix>::type,
        TransparentHandle<double, IsMutable> > type;
};

// DynamicStructRootContainer<Storage, TypeTraits>

template <class Storage, template <class T> class TypeTraits>
DynamicStructRootContainer<Storage, TypeTraits>::DynamicStructRootContainer(
    const DynamicStructRootContainer<Storage, TypeTraits>::Storage_type&
        inStorage)
  : mByteStreamBuf(inStorage) { }

template <class Storage, template <class T> class TypeTraits>
const typename DynamicStructRootContainer<Storage, TypeTraits>::StreamBuf_type&
DynamicStructRootContainer<Storage, TypeTraits>::streambuf() const {
    return mByteStreamBuf;
}

template <class Storage, template <class T> class TypeTraits>
typename DynamicStructRootContainer<Storage, TypeTraits>::StreamBuf_type&
DynamicStructRootContainer<Storage, TypeTraits>::streambuf() {
    return
        const_cast<StreamBuf_type&>(
            static_cast<const DynamicStructRootContainer*>(this)->streambuf()
        );
}


// DynamicStructBase<Derived, Container, IsMutable>

template <class Derived, class Container, bool IsMutable>
inline
DynamicStructBase<Derived, Container, IsMutable>::DynamicStructBase(
    Init_type& inContainer)
  : mContainer(inContainer) { }


template <class Derived, class Container, bool IsMutable>
inline
const typename DynamicStructBase<Derived, Container, IsMutable>
    ::RootContainer_type&
DynamicStructBase<Derived, Container, IsMutable>::rootContainer() const {
    return mContainer.rootContainer();
}

template <class Derived, class Container, bool IsMutable>
void
DynamicStructBase<Derived, Container, IsMutable>::initialize() { }


template <class Derived, bool IsMutable, class Storage,
    template <class T> class TypeTraits>
inline
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>
    ::DynamicStructBase(Init_type& inStorage)
  : mContainer(inStorage), mByteStream(&mContainer.streambuf()) { }

template <class Derived, bool IsMutable, class Storage,
    template <class T> class TypeTraits>
inline
const typename DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>,
    IsMutable>::RootContainer_type&
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>
    ::rootContainer() const {

    return static_cast<RootContainer_type&>(*this);
}

template <class Derived, bool IsMutable, class Storage, template <class T> class TypeTraits>
inline
const typename DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>,
    IsMutable>::Storage_type&
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>
    ::storage() const {

    return mContainer.streambuf().storage();
}

template <class Derived, bool IsMutable, class Storage,
    template <class T> class TypeTraits>
inline
const typename DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>
    ::ByteStream_type&
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>::byteStream()
    const {

    return mByteStream;
}


// DynamicStructBase<Derived, Container, Mutable>

template <class Derived, class Container>
template <class SubStruct>
void
DynamicStructBase<Derived, Container, Mutable>::setSize(
    SubStruct& inSubStruct, size_t inSize) {

    Base::mContainer.setSize(inSubStruct, inSize);
}

/**
 * @brief Change the size of a sub-struct
 */
template <class Derived, class Storage, template <class T> class TypeTraits>
template <class SubStruct>
inline
void
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, Mutable>::setSize(
    SubStruct& inSubStruct, size_t inSize) {

    if (inSubStruct.size() == inSize)
        return;

    typename Container_type::StreamBuf_type& streamBuf
        = mContainer.streambuf();
    streamBuf.resize(streamBuf.size() + inSize - inSubStruct.size(),
        inSubStruct.end());
    mByteStream.seek(0, std::ios_base::beg);
    mByteStream >> static_cast<Derived&>(*this);

    if (mByteStream.eof())
        throw std::runtime_error("Out-of-bounds byte-string access "
            "detected during resize.");
}


// DynamicStructBase<Derived, DynamicStructRootContainer<Storage, TypeTraits>,
//     IsMutable>

template <class Derived, bool IsMutable, class Storage,
    template <class T> class TypeTraits>
inline
void
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, IsMutable>::initialize() {

    mByteStream.seek(0, std::ios_base::beg);
    mByteStream >> static_cast<Derived&>(*this);

    if (mByteStream.eof()) {
        // The assumption is that either
        // a) we have a valid dynamic struct, in which case we do not end here
        // b) we have an uninitialized dynamic struct, which only consists of
        //    (too few) zero bytes.
        // If (b) is violated, then mByteStream.tell() might not have the
        // correct size information.

        typedef typename Container_type::StreamBuf_type StreamBuf_type;

        StreamBuf_type& streamBuf = mContainer.streambuf();
        streamBuf = StreamBuf_type(mByteStream.tell());
        mByteStream.seek(0, std::ios_base::beg);
        mByteStream >> static_cast<Derived&>(*this);

        if (mByteStream.eof())
            throw std::runtime_error("Out-of-bounds byte-string access "
                "detected during initialization of mutable dynamic struct.");
    }
}


// DynamicStructBase<Derived, DynamicStructRootContainer<Storage, TypeTraits>,
//     Mutable>

/* FIXME: Remove this.

template <class Derived, class Storage, template <class T> class TypeTraits>
inline
void
DynamicStructBase<Derived,
    DynamicStructRootContainer<Storage, TypeTraits>, Mutable>::initialize() {

    mByteStream.seek(0, std::ios_base::beg);
    mByteStream >> static_cast<Derived&>(*this);
    if (mByteStream.eof()) {
        typename Container_type::StreamBuf_type& streamBuf
            = mContainer.streambuf();
        streamBuf.resize(mByteStream.tell(), streamBuf.size());
        mByteStream.seek(0, std::ios_base::beg);
        mByteStream >> static_cast<Derived&>(*this);

        if (mByteStream.eof())
            throw std::runtime_error("Out-of-bounds byte-string access "
                "detected during initialization of mutable dynamic struct.");
    }
}
*/

// DynamicStruct<Derived, Container, IsMutable>

template <class Derived, class Container, bool IsMutable>
inline
DynamicStruct<Derived, Container, IsMutable>::DynamicStruct(Init_type& inInitialization)
  : Base(inInitialization) { }

template <class Derived, class Container, bool IsMutable>
inline
typename DynamicStruct<Derived, Container, IsMutable>::RootContainer_type&
DynamicStruct<Derived, Container, IsMutable>::rootContainer() {
    return const_cast<RootContainer_type&>(
        static_cast<const DynamicStruct*>(this)->rootContainer()
    );
}

template <class Derived, class Container, bool IsMutable>
inline
typename DynamicStruct<Derived, Container, IsMutable>::Storage_type&
DynamicStruct<Derived, Container, IsMutable>::storage() {
    return const_cast<Storage_type&>(
        static_cast<const DynamicStruct*>(this)->storage()
    );
}

template <class Derived, class Container, bool IsMutable>
inline
typename DynamicStruct<Derived, Container, IsMutable>::ByteStream_type&
DynamicStruct<Derived, Container, IsMutable>::byteStream() {
    return const_cast<ByteStream_type&>(
        static_cast<const DynamicStruct*>(this)->byteStream()
    );
}

template <class Derived, class Container, bool IsMutable>
inline
size_t
DynamicStruct<Derived, Container, IsMutable>::begin() const {
    return mBegin;
}

template <class Derived, class Container, bool IsMutable>
inline
size_t
DynamicStruct<Derived, Container, IsMutable>::end() const {
    return mEnd;
}

template <class Derived, class Container, bool IsMutable>
inline
typename DynamicStruct<Derived, Container, IsMutable>::char_type*
DynamicStruct<Derived, Container, IsMutable>::ptr() {
    return const_cast<char_type*>(
        static_cast<const DynamicStruct*>(this)->ptr()
    );
}

template <class Derived, class Container, bool IsMutable>
inline
const typename DynamicStruct<Derived, Container, IsMutable>::char_type*
DynamicStruct<Derived, Container, IsMutable>::ptr() const {
    return this->storage().ptr() + begin();
}

template <class Derived, class Container, bool IsMutable>
inline
size_t
DynamicStruct<Derived, Container, IsMutable>::size() const {
    return end() - begin();
}

/*
 * Note that there is also a version for
 * DynamicStruct<Derived, Container, Mutable>!
 */
template <class Derived, class Container, bool IsMutable>
inline
void
DynamicStruct<Derived, Container, IsMutable>::bindToStream(
    typename DynamicStruct<Derived, Container, IsMutable>::ByteStream_type&
        inStream) {

    inStream.template seek<ByteStream_type::maximumAlignment>(0,
        std::ios_base::cur);

    if (!inStream.isInDryRun())
        this->mBegin = inStream.tell();

    static_cast<Derived*>(this)->bind(inStream);
    inStream.template seek<ByteStream_type::maximumAlignment>(0,
        std::ios_base::cur);

    if (!inStream.isInDryRun())
        this->mEnd = inStream.tell();
}


// DynamicStruct<Derived, Container, Mutable>

template <class Derived, class Container>
inline
DynamicStruct<Derived, Container, Mutable>::DynamicStruct(
    Init_type& inInitialization)
  : Base(inInitialization), mSizeIsLocked(false) { }


/**
 * @brief Internal function to change size.
 *
 * This assumes that \c inSize is the correct size!
 */
template <class Derived, class Container>
inline
void
DynamicStruct<Derived, Container, Mutable>::setSize(size_t inSize) {
    this->setSize(static_cast<Derived&>(*this), inSize);
    Base::mEnd = Base::mBegin + inSize;
}

template <class Derived, class Container>
inline
void
DynamicStruct<Derived, Container, Mutable>::resize() {
    size_t begin = this->begin();
    ByteStream_type& stream = this->byteStream();
    stream.seek(begin, std::ios_base::beg);

    // We use an RAII object here that ensure that dry mode will also be
    // left in case of exceptions
    typename ByteStream_type::DryRun dryRun(stream);
    stream >> static_cast<Derived&>(*this);
    dryRun.leave();

    stream.template seek<ByteStream_type::maximumAlignment>(0,
        std::ios_base::cur);
    size_t newEnd = stream.tell();
    this->setSize(newEnd - begin);
}

template <class Derived, class Container>
template <class OtherDerived>
DynamicStruct<Derived, Container, Mutable>&
DynamicStruct<Derived, Container, Mutable>::copy(
        const OtherDerived &inOtherStruct) {

    if (this->size() != inOtherStruct.size()) {
        this->setSize(inOtherStruct.size());
        mSizeIsLocked = true;
    }

    // We now have enough space to copy everything from inOtherStruct
    std::copy(inOtherStruct.ptr(),
              inOtherStruct.ptr() + this->size(),
              this->ptr());

    mSizeIsLocked = false;
    this->resize();
    return *this;
}

/*
 * This method is overridden to take special care of the case when
 * <tt>mSizeIsLocked == true</tt>.
 */
template <class Derived, class Container>
inline
void
DynamicStruct<Derived, Container, Mutable>::bindToStream(
    typename DynamicStruct<Derived, Container, Mutable>::ByteStream_type&
        inStream) {

    inStream.template seek<ByteStream_type::maximumAlignment>(0,
        std::ios_base::cur);

    size_t begin = inStream.tell();
    size_t size = this->size();

    if (!inStream.isInDryRun())
        this->mBegin = begin;

    static_cast<Derived*>(this)->bind(inStream);

    if (mSizeIsLocked)
        inStream.template seek(begin + size, std::ios_base::beg);
    else
        inStream.template seek<ByteStream_type::maximumAlignment>(0,
            std::ios_base::cur);

    if (!inStream.isInDryRun())
        this->mEnd = inStream.tell();
}

} // namespace dbal

} // namespace madlib

#endif // defined(MADLIB_POSTGRES_DYNAMICSTRUCT_IMPL_HPP)
