/*
 * Copyright (c) 2017-2018 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_MEMORYGROUPBASE_H__
#define __ARM_COMPUTE_MEMORYGROUPBASE_H__

#include "arm_compute/runtime/IMemoryGroup.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/runtime/IMemoryManager.h"
#include "arm_compute/runtime/IMemoryPool.h"

#include <cstddef>
#include <memory>

namespace arm_compute
{
/** Memory group */
template <typename TensorType>
class MemoryGroupBase : public IMemoryGroup
{
public:
    /** Default Constructor */
    MemoryGroupBase(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
    /** Default destructor */
    ~MemoryGroupBase() = default;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    MemoryGroupBase(const MemoryGroupBase &) = delete;
    /** Prevent instances of this class from being copy assigned (As this class contains pointers) */
    MemoryGroupBase &operator=(const MemoryGroupBase &) = delete;
    /** Allow instances of this class to be moved */
    MemoryGroupBase(MemoryGroupBase &&) = default;
    /** Allow instances of this class to be moved */
    MemoryGroupBase &operator=(MemoryGroupBase &&) = default;
    /** Sets a object to be managed by the given memory group
     *
     * @note Manager must not be finalized
     *
     * @param[in] obj Object to be managed
     */
    void manage(TensorType *obj);
    /** Finalizes memory for a given object
     *
     * @note Manager must not be finalized
     *
     * @param[in] obj    Object to request memory for
     * @param[in] handle Handle to store the memory
     * @param[in] size   Size of memory to allocate
     */
    void finalize_memory(TensorType *obj, void **handle, size_t size);

    // Inherited methods overridden:
    void            acquire() override;
    void            release() override;
    MemoryMappings &mappings() override;

private:
    void associate_memory_group(TensorType *obj);

private:
    std::shared_ptr<IMemoryManager> _memory_manager; /**< Memory manager to be used by the group */
    IMemoryPool                    *_pool;           /**< Memory pool that the group is scheduled with */
    MemoryMappings                  _mappings;       /**< Memory mappings of the group */
};

template <typename TensorType>
inline MemoryGroupBase<TensorType>::MemoryGroupBase(std::shared_ptr<IMemoryManager> memory_manager)
    : _memory_manager(std::move(memory_manager)), _pool(nullptr), _mappings()
{
    if(_memory_manager)
    {
        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
    }
}

template <typename TensorType>
inline void MemoryGroupBase<TensorType>::manage(TensorType *obj)
{
    if(_memory_manager && _mappings.empty())
    {
        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());

        // Defer registration to the first managed object
        _memory_manager->lifetime_manager()->register_group(this);

        // Associate this memory group with the tensor
        associate_memory_group(obj);

        // Start object lifetime
        _memory_manager->lifetime_manager()->start_lifetime(obj);
    }
}

template <typename TensorType>
inline void MemoryGroupBase<TensorType>::finalize_memory(TensorType *obj, void **handle, size_t size)
{
    // TODO (geopin01) : Check size (track size in MemoryMappings)
    // Check if existing mapping is valid
    ARM_COMPUTE_ERROR_ON(!_mappings.empty() && (_mappings.find(handle) == std::end(_mappings)));

    if(_memory_manager && _mappings.empty())
    {
        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
        _memory_manager->lifetime_manager()->end_lifetime(obj, handle, size);
    }
}

template <typename TensorType>
inline void MemoryGroupBase<TensorType>::acquire()
{
    if(!_mappings.empty())
    {
        ARM_COMPUTE_ERROR_ON(!_memory_manager->pool_manager());
        _pool = _memory_manager->pool_manager()->lock_pool();
        _pool->acquire(_mappings);
    }
}

template <typename TensorType>
inline void MemoryGroupBase<TensorType>::release()
{
    if(_pool != nullptr)
    {
        ARM_COMPUTE_ERROR_ON(!_memory_manager->pool_manager());
        ARM_COMPUTE_ERROR_ON(_mappings.empty());
        _pool->release(_mappings);
        _memory_manager->pool_manager()->unlock_pool(_pool);
        _pool = nullptr;
    }
}

template <typename TensorType>
inline MemoryMappings &MemoryGroupBase<TensorType>::mappings()
{
    return _mappings;
}

template <typename TensorType>
inline void MemoryGroupBase<TensorType>::associate_memory_group(TensorType *)
{
    ARM_COMPUTE_ERROR("Must be implemented by child class");
}
} // arm_compute
#endif /*__ARM_COMPUTE_MEMORYGROUPBASE_H__ */
