/*
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "MainLoop.h"

#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE

#include <errno.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <pthread.h>

namespace chip {
namespace DeviceLayer {
namespace Internal {

namespace {

class Semaphore
{
public:
    Semaphore()
    {
        if (sem_init(&mSemaphore, 0 /* shared */, 0 /*value*/) != 0)
        {
            ChipLogError(DeviceLayer, "Failed to initialize semaphore.");
        }
    }

    ~Semaphore()
    {
        if (sem_destroy(&mSemaphore) != 0)
        {
            ChipLogError(DeviceLayer, "Failed to destroy semaphore.");
        }
    }

    void Post() { sem_post(&mSemaphore); }

    void Wait() { sem_wait(&mSemaphore); }

private:
    sem_t mSemaphore;
};

int PostSemaphore(Semaphore * semaphore)
{
    semaphore->Post();
    return 0;
}

class CallbackIndirection
{
public:
    CallbackIndirection(GSourceFunc f, void * a) : mCallback(f), mArgument(a) {}

    void Wait() { mDoneSemaphore.Wait(); }

    static int Callback(CallbackIndirection * self)
    {
        int result = self->mCallback(self->mArgument);
        self->mDoneSemaphore.Post();
        return result;
    }

private:
    Semaphore mDoneSemaphore;
    GSourceFunc mCallback;
    void * mArgument;
};

} // namespace

MainLoop & MainLoop::Instance()
{
    static MainLoop sMainLoop;
    return sMainLoop;
}

void * MainLoop::Thread(void * self)
{
    MainLoop * loop = reinterpret_cast<MainLoop *>(self);

    ChipLogDetail(DeviceLayer, "TRACE: Bluez mainloop starting %s", __func__);
    g_main_loop_run(loop->mBluezMainLoop);
    ChipLogDetail(DeviceLayer, "TRACE: Bluez mainloop stopping %s", __func__);

    if (loop->mCleanup != nullptr)
    {
        ChipLogDetail(DeviceLayer, "TRACE: Executing cleanup %s", __func__);
        loop->mCleanup(loop->mCleanupArgument);
    }

    return nullptr;
}

CHIP_ERROR MainLoop::EnsureStarted()
{
    if (mBluezMainLoop != nullptr)
    {
        return CHIP_NO_ERROR;
    }

    mBluezMainLoop = g_main_loop_new(nullptr, TRUE);
    if (mBluezMainLoop == nullptr)
    {
        ChipLogError(DeviceLayer, "FAIL: memory alloc in %s", __func__);
        return CHIP_ERROR_NO_MEMORY;
    }

    int pthreadErr = pthread_create(&mThread, nullptr, &MainLoop::Thread, reinterpret_cast<void *>(this));
#if CHIP_ERROR_LOGGING
    int tmpErrno = errno;
#endif // CHIP_ERROR_LOGGING
    if (pthreadErr != 0)
    {
        ChipLogError(DeviceLayer, "FAIL: pthread_create (%s) in %s", strerror(tmpErrno), __func__);
        g_free(mBluezMainLoop);
        mBluezMainLoop = nullptr;
        return CHIP_ERROR_INTERNAL;
    }

    Semaphore semaphore;

    GMainContext * context = g_main_loop_get_context(mBluezMainLoop);
    VerifyOrDie(context != nullptr);

    g_main_context_invoke(context, GSourceFunc(PostSemaphore), &semaphore);

    semaphore.Wait();

    return CHIP_NO_ERROR;
}

bool MainLoop::RunOnBluezThread(GSourceFunc callback, void * argument)
{
    GMainContext * context = nullptr;
    const char * msg       = nullptr;

    VerifyOrExit(mBluezMainLoop != nullptr, msg = "FAIL: NULL sBluezMainLoop");
    VerifyOrExit(g_main_loop_is_running(mBluezMainLoop), msg = "FAIL: sBluezMainLoop not running");

    context = g_main_loop_get_context(mBluezMainLoop);
    VerifyOrExit(context != nullptr, msg = "FAIL: NULL main context");
    g_main_context_invoke(context, callback, argument);

exit:
    if (msg != nullptr)
    {
        ChipLogDetail(DeviceLayer, "%s in %s", msg, __func__);
    }

    return msg == nullptr;
}

bool MainLoop::RunOnBluezThreadAndWait(GSourceFunc closure, void * argument)
{
    CallbackIndirection indirection(closure, argument);

    if (!Schedule(&CallbackIndirection::Callback, &indirection))
    {
        return false;
    }

    indirection.Wait();

    return true;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip

#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
