/*
   HARK Library
   Copyright (C) 2021 Honda Research Institute Japan Inc.
 */

#include "hark-lib/hark-lib.h"

#include "hark-lib/internal/thread.h"
#include "hark-lib/internal/mutex.h"
#include "hark-lib/internal/condition_variable.h"
#include "hark-lib/internal/lock.h"

#include <condition_variable>
#include <mutex>

namespace hark
{
    void
    Thread::join()
    {
        this->_thread.join();
    }

    // class MutexImpl: public MutexBaseImpl
    // {
    // public:
    //     virtual void lock() override
    //     {
    //         this->_mutex.lock();
    //     }

    //     virtual void unlock() override
    //     {
    //         this->_mutex.unlock();
    //     }

    // public:
    //     std::mutex _mutex;
    // };

    // Mutex::Mutex(): _impl(new MutexImpl())
    // {
    // }

    Mutex::Mutex(): _impl(new std::mutex())
    {
    }

    // UniqueLockBaseImpl::UniqueLockBaseImpl(Mutex &mutex)
    // {
    // }

    // class UniqueLockImpl: public UniqueLockBaseImpl
    // {
    // public:
    //     UniqueLockImpl(Mutex &mutex): UniqueLockBaseImpl(mutex), _lock(dynamic_cast<MutexImpl *>(mutex._impl.get())->_mutex) {}

    // public:
    //     std::unique_lock<std::mutex> _lock;
    // };

    // UniqueMutexLock::UniqueMutexLock(Mutex &mutex):
    //     _impl(new UniqueLockImpl(mutex))
    // {
    // }

    // UniqueMutexLock::UniqueMutexLock(Mutex *mutex):
    //     _impl(new UniqueLockImpl(*mutex))
    // {
    // }

    // class ConditionVariableImpl: public ConditionVariableBaseImpl
    // {
    // public:
    //     virtual void wait(UniqueLock<Mutex> &lock) override
    //     {
    //         this->_condition_variable.wait(dynamic_cast<UniqueLockImpl *>(lock._impl.get())->_lock);
    //     }

    //     virtual void wait(UniqueLock<Mutex> &lock, std::function<bool()> pred) override
    //     {
    //         this->_condition_variable.wait(dynamic_cast<UniqueLockImpl *>(lock._impl.get())->_lock, pred);
    //     }

    //     virtual void notify_one() override
    //     {
    //         this->_condition_variable.notify_one();
    //     }

    // private:
    //     std::condition_variable _condition_variable;
    // };

    // ConditionVariable::ConditionVariable():
    //     _impl(new ConditionVariableImpl())
    // {
    // }

    UniqueLock::UniqueLock(Mutex &mutex):
        _impl(*mutex._impl)
    {
    }
 
    UniqueLock::UniqueLock(Mutex *mutex):
        _impl(*mutex->_impl)
    {
    }

    ConditionVariable::ConditionVariable():
        _impl(new std::condition_variable())
    {
    }

    void
    ConditionVariable::wait(UniqueLock& lock)
    {
        this->_impl->wait(lock._impl);
    }

    void
    ConditionVariable::wait(UniqueLock &lock, std::function<bool()> pred)
    {
        this->_impl->wait(lock._impl, pred);
    }

    void
    ConditionVariable::notify_one()
    {
        this->_impl->notify_one();
    }

}

/* end of file */
