/*
 *  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 "webrtc/modules/interface/module.h"
#include "webrtc/modules/utility/source/process_thread_impl.h"


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

ProcessThread* ProcessThread::CreateProcessThread()
{
    return new ProcessThreadImpl();
}

void ProcessThread::DestroyProcessThread(ProcessThread* module)
{
    delete module;
}

ProcessThreadImpl::ProcessThreadImpl()
    : _timeEvent(*EventWrapper::Create()),
      _critSectModules(CriticalSectionWrapper::CreateCriticalSection()),
      _thread(NULL)
{
}

ProcessThreadImpl::~ProcessThreadImpl()
{
    delete _critSectModules;
    delete &_timeEvent;
}

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

int32_t 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;
}

int32_t ProcessThreadImpl::RegisterModule(Module* module)
{
    CriticalSectionScoped lock(_critSectModules);

    // Only allow module to be registered once.
    for (ModuleList::iterator iter = _modules.begin();
         iter != _modules.end(); ++iter) {
        if(module == *iter)
        {
            return -1;
        }
    }

    _modules.push_front(module);

    // 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;
}

int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
{
    CriticalSectionScoped lock(_critSectModules);
    for (ModuleList::iterator iter = _modules.begin();
         iter != _modules.end(); ++iter) {
        if(module == *iter)
        {
            _modules.erase(iter);
            return 0;
        }
    }
    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.
    int32_t minTimeToNext = 100;
    {
        CriticalSectionScoped lock(_critSectModules);
        for (ModuleList::iterator iter = _modules.begin();
             iter != _modules.end(); ++iter) {
          int32_t timeToNext = (*iter)->TimeUntilNextProcess();
            if(minTimeToNext > timeToNext)
            {
                minTimeToNext = timeToNext;
            }
        }
    }

    if(minTimeToNext > 0)
    {
        if(kEventError == _timeEvent.Wait(minTimeToNext))
        {
            return true;
        }
        CriticalSectionScoped lock(_critSectModules);
        if(!_thread)
        {
            return false;
        }
    }
    {
        CriticalSectionScoped lock(_critSectModules);
        for (ModuleList::iterator iter = _modules.begin();
             iter != _modules.end(); ++iter) {
          int32_t timeToNext = (*iter)->TimeUntilNextProcess();
            if(timeToNext < 1)
            {
                (*iter)->Process();
            }
        }
    }
    return true;
}
}  // namespace webrtc
