/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "channel_manager_base.h"

#include "critical_section_wrapper.h"
#include "rw_lock_wrapper.h"
#include <cassert>

namespace webrtc
{

namespace voe
{

ChannelManagerBase::ChannelManagerBase() :
    _itemsCritSectPtr(CriticalSectionWrapper::CreateCriticalSection()),
    _itemsRWLockPtr(RWLockWrapper::CreateRWLock())
{
    for (int i = 0; i < KMaxNumberOfItems; i++)
    {
        _freeItemIds[i] = true;
    }
}

ChannelManagerBase::~ChannelManagerBase()
{
    if (_itemsRWLockPtr)
    {
        delete _itemsRWLockPtr;
        _itemsRWLockPtr = NULL;
    }
    if (_itemsCritSectPtr)
    {
        delete _itemsCritSectPtr;
        _itemsCritSectPtr = NULL;
    }
}

bool ChannelManagerBase::GetFreeItemId(WebRtc_Word32& itemId)
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    WebRtc_Word32 i(0);
    while (i < KMaxNumberOfItems)
    {
        if (_freeItemIds[i])
        {
            itemId = i;
            _freeItemIds[i] = false;
            return true;
        }
        i++;
    }
    return false;
}

void ChannelManagerBase::AddFreeItemId(WebRtc_Word32 itemId)
{
    assert(itemId < KMaxNumberOfItems);
    _freeItemIds[itemId] = true;
}

void ChannelManagerBase::RemoveFreeItemIds()
{
    for (int i = 0; i < KMaxNumberOfItems; i++)
    {
        _freeItemIds[i] = false;
    }
}

bool ChannelManagerBase::CreateItem(WebRtc_Word32& itemId)
{
    _itemsCritSectPtr->Enter();
    void* itemPtr;
    itemId = -1;
    const bool success = GetFreeItemId(itemId);
    if (!success)
    {
        _itemsCritSectPtr->Leave();
        return false;
    }
    itemPtr = NewItem(itemId);
    if (!itemPtr)
    {
        _itemsCritSectPtr->Leave();
        return false;
    }
    _itemsCritSectPtr->Leave();
    InsertItem(itemId, itemPtr);

    return true;
}

void ChannelManagerBase::InsertItem(WebRtc_Word32 itemId, void* item)
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    assert(!_items.Find(itemId));
    _items.Insert(itemId, item);
}

void*
ChannelManagerBase::RemoveItem(WebRtc_Word32 itemId)
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    WriteLockScoped wlock(*_itemsRWLockPtr);
    MapItem* it = _items.Find(itemId);
    if (!it)
    {
        return 0;
    }
    void* returnItem = it->GetItem();
    _items.Erase(it);
    AddFreeItemId(itemId);

    return returnItem;
}

void ChannelManagerBase::DestroyAllItems()
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    MapItem* it = _items.First();
    while (it)
    {
        DeleteItem(it->GetItem());
        _items.Erase(it);
        it = _items.First();
    }
    RemoveFreeItemIds();
}

WebRtc_Word32 ChannelManagerBase::NumOfItems() const
{
    return _items.Size();
}

WebRtc_Word32 ChannelManagerBase::MaxNumOfItems() const
{
    return static_cast<WebRtc_Word32> (KMaxNumberOfItems);
}

void*
ChannelManagerBase::GetItem(WebRtc_Word32 itemId) const
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    MapItem* it = _items.Find(itemId);
    if (!it)
    {
        return 0;
    }
    _itemsRWLockPtr->AcquireLockShared();
    return it->GetItem();
}

void*
ChannelManagerBase::GetFirstItem(void*& iterator) const
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    MapItem* it = _items.First();
    iterator = (void*) it;
    if (!it)
    {
        return 0;
    }
    return it->GetItem();
}

void*
ChannelManagerBase::GetNextItem(void*& iterator) const
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    MapItem* it = (MapItem*) iterator;
    if (!it)
    {
        iterator = 0;
        return 0;
    }
    it = _items.Next(it);
    iterator = (void*) it;
    if (!it)
    {
        return 0;
    }
    return it->GetItem();
}

void ChannelManagerBase::ReleaseItem()
{
    _itemsRWLockPtr->ReleaseLockShared();
}

void ChannelManagerBase::GetItemIds(WebRtc_Word32* channelsArray,
                                    WebRtc_Word32& numOfChannels) const
{
    MapItem* it = _items.First();
    numOfChannels = (numOfChannels <= _items.Size()) ?
        numOfChannels : _items.Size();
    for (int i = 0; i < numOfChannels && it != NULL; i++)
    {
        channelsArray[i] = it->GetId();
        it = _items.Next(it);
    }
}

void ChannelManagerBase::GetChannels(MapWrapper& channels) const
{
    CriticalSectionScoped cs(*_itemsCritSectPtr);
    if (_items.Size() == 0)
    {
        return;
    }
    _itemsRWLockPtr->AcquireLockShared();
    for (MapItem* it = _items.First(); it != NULL; it = _items.Next(it))
    {
        channels.Insert(it->GetId(), it->GetItem());
    }
}

} // namespace voe

} // namespace webrtc
