#include "tile/base/thread/mutex.h"

#include "tile/base/make_unique.h"

#include <mutex>

namespace tile {

class Mutex::Impl {
public:
    inline void Lock() { m_.lock(); }

    inline bool TryLock() { return m_.try_lock(); }

    inline void Unlock() { m_.unlock(); }

    inline void *GetNativeHandle() { return reinterpret_cast<void *>(&m_); };

private:
    std::mutex m_;
};

class RecursiveMutex::Impl {
public:
    inline void Lock() { m_.lock(); }

    inline bool TryLock() { return m_.try_lock(); }

    inline void Unlock() { m_.unlock(); }

private:
    std::recursive_mutex m_;
};

Mutex::Mutex() : impl_(make_unique<Impl>()) {}

Mutex::~Mutex() {}

void
Mutex::Lock()
{
    impl_->Lock();
}

bool
Mutex::TryLock()
{
    return impl_->TryLock();
}

void
Mutex::Unlock()
{
    impl_->Unlock();
}

void *
Mutex::GetNativeHandle()
{
    return impl_->GetNativeHandle();
}

RecursiveMutex::RecursiveMutex() : impl_(make_unique<Impl>()) {}

RecursiveMutex::~RecursiveMutex() {}

void
RecursiveMutex::Lock()
{
    impl_->Lock();
}

bool
RecursiveMutex::TryLock()
{
    return impl_->TryLock();
}

void
RecursiveMutex::Unlock()
{
    impl_->Unlock();
}

}// namespace tile
