/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/

#include <tlm_utils/instance_specific_extensions_int.h>

#include <iostream>
#include <map>
#include <systemc>
#include <tlm>
#include <typeindex>

namespace tlm
{

template class tlm_array<tlm_utils::ispex_base *>;

} // namespace tlm

namespace tlm_utils
{

namespace
{

class ispex_registry // Copied from tlm_gp.cpp.
{
    typedef unsigned int key_type;
    typedef std::map<std::type_index, key_type> type_map;

  public:
    static ispex_registry &
    instance()
    {
        if (!instance_) {
            // Don't cleanup registry.
            instance_ = new ispex_registry();
        }
        return *instance_;
    }

    unsigned int
    register_extension(std::type_index type)
    {
        type_map::const_iterator it = ids_.find(type);

        if (it == ids_.end()) {
            // New extension - generate/store ID.
            type_map::value_type v(type, static_cast<key_type>(ids_.size()));
            ids_.insert(v);
            return v.second;
        }
        return it->second;
    }

    static unsigned int
    max_num_extensions()
    {
        return (instance_) ? instance().ids_.size() : 0;
    }

  private:
    static ispex_registry *instance_;
    type_map ids_;
    ispex_registry() {}
};

ispex_registry *ispex_registry::instance_ = nullptr;

} //  anonymous namespace

unsigned int
ispex_base::register_private_extension(const std::type_info &type)
{
    return ispex_registry::instance().register_extension(type);
}

// Helper to do the numbering of private extension accessors.
static unsigned int
max_num_ispex_accessors(bool increment=false)
{
    static unsigned int max_num = 0;
    if (increment)
        ++max_num;
    return max_num;
}

// ----------------------------------------------------------------------------

// The pool for the container, plain as can be.
class instance_specific_extension_container_pool
{
    instance_specific_extension_container_pool() : unused(nullptr) {}
    ~instance_specific_extension_container_pool();

  public:
    static instance_specific_extension_container_pool &
    instance()
    {
        static instance_specific_extension_container_pool inst;
        return inst;
    }

    instance_specific_extension_container *create();
    void free(instance_specific_extension_container *);

  private:
    instance_specific_extension_container *unused;
};

instance_specific_extension_container *
instance_specific_extension_container_pool::create()
{
    if (!unused) {
        unused = new instance_specific_extension_container();
    }
    instance_specific_extension_container *tmp = unused;
    unused = unused->next;
    return tmp;
}

void
instance_specific_extension_container_pool::free(
        instance_specific_extension_container *cont)
{
    cont->next = unused;
    unused = cont;
}

instance_specific_extension_container_pool::
    ~instance_specific_extension_container_pool()
{
    while (unused) {
        instance_specific_extension_container *tmp = unused;
        unused = unused->next;
        delete tmp;
    }
}

// ----------------------------------------------------------------------------

instance_specific_extension_container *
instance_specific_extension_container::create()
{
    return instance_specific_extension_container_pool::instance().create();
}

instance_specific_extension_container::
    instance_specific_extension_container() :
    use_count(0), m_txn(NULL), m_release_fn(NULL), m_carrier(NULL), next(NULL)
{
    resize();
}

void
instance_specific_extension_container::
    attach_carrier(instance_specific_extension_carrier *carrier,
            void *txn, release_fn *rel_fn)
{
    m_txn = txn;
    m_release_fn = rel_fn;
    m_carrier = carrier;
}

void
instance_specific_extension_container::resize()
{
    m_ispex_per_accessor.resize(max_num_ispex_accessors());

    for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i) {
        m_ispex_per_accessor[i] =
            new instance_specific_extensions_per_accessor(this);
        m_ispex_per_accessor[i]->resize_extensions();
    }
}

instance_specific_extension_container::
    ~instance_specific_extension_container()
{
    for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i)
        delete m_ispex_per_accessor[i];
}

void
instance_specific_extension_container::inc_use_count()
{
    use_count++;
}

void
instance_specific_extension_container::dec_use_count()
{
    if ((--use_count) == 0) {
        // If this container isn't used any more we release the carrier
        // extension.
        m_release_fn(m_carrier, m_txn);
        // We send it back to our pool.
        instance_specific_extension_container_pool::instance().free(this);
    }
}

instance_specific_extensions_per_accessor *
instance_specific_extension_container::get_accessor(unsigned int idx)
{
    return m_ispex_per_accessor[idx];
}

// ----------------------------------------------------------------------------

// non-templatized version with manual index:
ispex_base *
instance_specific_extensions_per_accessor::set_extension(
        unsigned int index, ispex_base *ext)
{
    resize_extensions();
    ispex_base *tmp = m_extensions[index];
    m_extensions[index] = ext;
    if (!tmp && ext)
        m_container->inc_use_count();
    return tmp;
}

ispex_base *
instance_specific_extensions_per_accessor::get_extension(
        unsigned int index) const
{
    return (index < m_extensions.size()) ? m_extensions[index] : nullptr;
}

void
instance_specific_extensions_per_accessor::clear_extension(unsigned int index)
{
    if (index < m_extensions.size()) {
        if (m_extensions[index])
            m_container->dec_use_count();
        m_extensions[index] = static_cast<ispex_base *>(nullptr);
    }
}

void
instance_specific_extensions_per_accessor::resize_extensions()
{
    m_extensions.expand(ispex_registry::max_num_extensions());
}

// ----------------------------------------------------------------------------

instance_specific_extension_accessor::instance_specific_extension_accessor() :
    m_index(max_num_ispex_accessors(true) - 1)
{}

} // namespace tlm_utils
