#pragma once

#include <stdint.h>

#include <algorithm>
#include <memory>
#include <vector>

namespace libhei
{

/** @brief A generic flyweight factory for objects of type T. */
template <class T>
class Flyweight
{
  private: // This class cannot be instantiated. Use getSingleton() instead.
    /** @brief Default constructor. */
    Flyweight() = default;

    /** @brief Destructor. */
    ~Flyweight()
    {
        clear();
    }

    /** @brief Default copy constructor. */
    Flyweight(const Flyweight&) = delete;

    /** @brief Default assignment operator. */
    Flyweight& operator=(const Flyweight&) = delete;

  public:
    /** @brief Provides access to a singleton instance of this object. */
    static Flyweight& getSingleton()
    {
        static Flyweight theFlyweight;
        return theFlyweight;
    }

    /**
     * @brief  Does an emplace add of a new entry to the factory, if the entry
     *         does not already exist, and returns a pointer to the entry in the
     *         factory.
     * @param  An variable argument list that would be passed to a contructor of
     *         class T.
     * @return A pointer to this entry in the factory.
     */
    template <class... Args>
    std::shared_ptr<T> get(Args&&... i_args)
    {
        // Create a new instance with the given arguments.
        std::shared_ptr<T> newEntry = std::make_shared<T>(i_args...);

        // The index is sorted by the value of the T objects. Check to see if
        // newEntry already exists in the factory.
        auto itr = std::lower_bound(
            iv_index.begin(), iv_index.end(), newEntry,
            [](const std::shared_ptr<T> a, const std::shared_ptr<T> b) {
            return *a < *b;
        });

        // std::lower_bound() will return the first element that does not
        // compare less than newEntry. So if an element is found, we must make
        // sure it does not have the same value as newEntry.
        if (iv_index.end() == itr || !(*newEntry == *(*itr)))
        {
            // Store the new enty in the sorted index.
            itr = iv_index.insert(itr, newEntry);
        }

        // It is important to note that if newEntry was not inserted into the
        // index above because a duplicate already existed, it will be deleted
        // as soon as it goes out of scope.

        // Return a pointer to the this entry in the factory.
        return *itr;
    }

    /**
     * @brief Deletes all entries in the factory.
     *
     * This is called in the destructor. So it cannot throw an exception.
     */
    void clear()
    {
        iv_index.clear();
    }

    /**
     * @brief Shrinks the index capacity to eliminate unused memory space.
     *
     * The index is a vector where the capacity will grow as items are added to
     * it. Each time more capacity is needed, the vector will double the current
     * capacity to make room for new entries. The general use of this class is
     * expected that all needed entries will be added during the isolator
     * initialization. Afterwards, the extra capacity is not needed. So this
     * function will shrink the capacity to the size of the vector.
     */
    void compact()
    {
        iv_index.shrink_to_fit();
    }

    /** @return The number of entries in this flyweight factory. */
    size_t size()
    {
        return iv_index.size();
    }

  private:
    /**
     * Each new T is allocated on the memory heap and a pointer to each of those
     * objects is stored in this vector. The vector will not contain duplicates
     * and is kept sorted by the value of the objects. Inserting a new element
     * is O(n). However, since the vector is sorted, searching for existing
     * entries is O(log n). Considering the expected use of this class,
     * insertion should only exist during initialization of the isolator, where
     * searching will be done at the time of isolation when performance is more
     * important.
     *
     * An alternative to this approach is to use std::set, where insertion and
     * searching are both O(log n). However, std::set is typically designed with
     * a red-black tree which carries a lot of extra memory overhead to maintain
     * the structure. Also, the Hostboot user application does not support
     * std::set at this time.
     */
    std::vector<std::shared_ptr<T>> iv_index;
};

} // end namespace libhei
