/*
 *  Copyright (c) 2011 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 "process_thread_impl.h"
#include "module.h"
#include "trace.h"

namespace webrtc {
ProcessThread::~ProcessThread()
{
}

ProcessThread* ProcessThread::CreateProcessThread()
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "CreateProcessThread()");
    return new ProcessThreadImpl();
}

void ProcessThread::DestroyProcessThread(ProcessThread* module)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "DestroyProcessThread()");
    delete module;
}

ProcessThreadImpl::ProcessThreadImpl()
    : _timeEvent(*EventWrapper::Create()),
      _critSectModules(*CriticalSectionWrapper::CreateCriticalSection()),
      _thread(NULL)
{
    WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s created", __FUNCTION__);
}

ProcessThreadImpl::~ProcessThreadImpl()
{
    delete &_critSectModules;
    delete &_timeEvent;
    WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s deleted", __FUNCTION__);
}

WebRtc_Word32 ProcessThreadImpl::Start()
{
    CriticalSectionScoped lock(_critSectModules);
    if(_thread)
    {
        return -1;
    }
    _thread = ThreadWrapper::CreateThread(Run, this, kNormalPriority,
                                          "ProcessThread");
    unsigned int id;
    WebRtc_Word32 retVal = _thread->Start(id);
    if(retVal >= 0)
    {
        return 0;
    }
    delete _thread;
    _thread = NULL;
    return -1;
}

WebRtc_Word32 ProcessThreadImpl::Stop()
{
    _critSectModules.Enter();
    if(_thread)
    {
        _thread->SetNotAlive();

        ThreadWrapper* thread = _thread;
        _thread = NULL;

        _timeEvent.Set();
        _critSectModules.Leave();

        if(thread->Stop())
        {
            delete thread;
        } else {
            return -1;
        }
    } else {
        _critSectModules.Leave();
    }
    return 0;
}

WebRtc_Word32 ProcessThreadImpl::RegisterModule(const Module* module)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1,
                 "RegisterModule(module:0x%x)", module);
    CriticalSectionScoped lock(_critSectModules);

    // Only allow module to be registered once.
    ListItem* item = _modules.First();
    for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
    {
        if(module == item->GetItem())
        {
            return -1;
        }
        item = _modules.Next(item);
    }

    _modules.PushFront(module);
    WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
                 "number of registered modules has increased to %d",
                 _modules.GetSize());
    // Wake the thread calling ProcessThreadImpl::Process() to update the
    // waiting time. The waiting time for the just registered module may be
    // shorter than all other registered modules.
    _timeEvent.Set();
    return 0;
}

WebRtc_Word32 ProcessThreadImpl::DeRegisterModule(const Module* module)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1,
                 "DeRegisterModule(module:0x%x)", module);
    CriticalSectionScoped lock(_critSectModules);

    ListItem* item = _modules.First();
    for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
    {
        if(module == item->GetItem())
        {
            int res = _modules.Erase(item);
            WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
                         "number of registered modules has decreased to %d",
                         _modules.GetSize());
            return res;
        }
        item = _modules.Next(item);
    }
    return -1;
}

bool ProcessThreadImpl::Run(void* obj)
{
    return static_cast<ProcessThreadImpl*>(obj)->Process();
}

bool ProcessThreadImpl::Process()
{
    // Wait for the module that should be called next, but don't block thread
    // longer than 100 ms.
    WebRtc_Word32 minTimeToNext = 100;
    {
        CriticalSectionScoped lock(_critSectModules);
        ListItem* item = _modules.First();
        for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
        {
            WebRtc_Word32 timeToNext =
                static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
            if(minTimeToNext > timeToNext)
            {
                minTimeToNext = timeToNext;
            }
            item = _modules.Next(item);
        }
    }

    if(minTimeToNext > 0)
    {
        if(kEventError == _timeEvent.Wait(minTimeToNext))
        {
            return true;
        }
        if(!_thread)
        {
            return false;
        }
    }
    {
        CriticalSectionScoped lock(_critSectModules);
        ListItem* item = _modules.First();
        for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
        {
            WebRtc_Word32 timeToNext =
                static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
            if(timeToNext < 1)
            {
                static_cast<Module*>(item->GetItem())->Process();
            }
            item = _modules.Next(item);
        }
    }
    return true;
}
} // namespace webrtc
