#include "bean.h"

namespace zsy
{
    Bean::Bean()
        : state(BEAN_Uninitialized)
    {
    }

    bool Bean::waitForState(uint8_t state, const std::chrono::milliseconds timeout) const noexcept
    {
        std::shared_lock lck(stateMtx);
        return stateChangeCV.wait_for(lck, timeout, [this, state]
        {
            return this->state == state;
        });
    }

    bool Bean::waitStarted(const std::chrono::milliseconds timeout) const noexcept
    {
        std::shared_lock lck(stateMtx);
        return stateChangeCV.wait_for(lck, timeout, [this]
        {
            return state == BEAN_Available || state == BEAN_Terminated;
        });
    }

    bool Bean::waitStopped(const std::chrono::milliseconds timeout) const noexcept
    {
        std::shared_lock lck(stateMtx);
        return stateChangeCV.wait_for(lck, timeout, [this]
        {
            return state == BEAN_Terminated;
        });
    }

    void Bean::reportUninitialized() noexcept
    {
        std::unique_lock<std::shared_mutex> lck(stateMtx);
        if (state == BEAN_Terminated) return;
        state = BEAN_Uninitialized;
        stateChangeCV.notify_all();
    }

    void Bean::reportInitializing() noexcept
    {
        std::unique_lock<std::shared_mutex> lck(stateMtx);
        if (state == BEAN_Terminated) return;
        state = BEAN_Initializing;
        stateChangeCV.notify_all();
    }

    void Bean::reportAvailable() noexcept
    {
        std::unique_lock<std::shared_mutex> lck(stateMtx);
        if (state == BEAN_Terminated) return;
        state = BEAN_Available;
        stateChangeCV.notify_all();
    }

    void Bean::reportDestroying() noexcept
    {
        std::unique_lock<std::shared_mutex> lck(stateMtx);
        if (state == BEAN_Terminated) return;
        state = BEAN_Destroying;
        stateChangeCV.notify_all();
    }

    void Bean::reportTerminated() noexcept
    {
        std::unique_lock<std::shared_mutex> lck(stateMtx);
        state = BEAN_Terminated;
        stateChangeCV.notify_all();
    }

    uint8_t Bean::getState() const noexcept
    {
        std::shared_lock lck(stateMtx);
        return state;
    }

    bool Bean::canUse() const noexcept
    {
        std::shared_lock lck(stateMtx);
        return state == BEAN_Available;
    }
} // zsy