/*
 *
 *    Copyright (c) 2020-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.
 */

/**
 *    @file
 *      This file declares the abstraction of one-directional, anonymous
 *      data stream built on top of two file descriptors.
 */

#include <system/SystemConfig.h>

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

#include <system/WakeEvent.h>

// Include additional CHIP headers
#include <lib/support/CodeUtils.h>
#include <system/SystemError.h>
#include <system/SystemLayer.h>

// Include system and language headers
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#if !CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
#include <sys/eventfd.h>
#endif

namespace chip {
namespace System {

#if CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE

namespace {
inline int SetNonBlockingMode(int fd)
{
    int flags = ::fcntl(fd, F_GETFL, 0);
    return ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
} // anonymous namespace

CHIP_ERROR WakeEvent::Open(LayerSockets & systemLayer)
{
    enum
    {
        FD_READ  = 0,
        FD_WRITE = 1
    };
    int fds[2];

    if (::pipe(fds) < 0)
        return CHIP_ERROR_POSIX(errno);

    if (SetNonBlockingMode(fds[FD_READ]) < 0)
        return CHIP_ERROR_POSIX(errno);

    if (SetNonBlockingMode(fds[FD_WRITE]) < 0)
        return CHIP_ERROR_POSIX(errno);

    mReadFD  = fds[FD_READ];
    mWriteFD = fds[FD_WRITE];

    ReturnErrorOnFailure(systemLayer.StartWatchingSocket(mReadFD, &mReadWatch));
    ReturnErrorOnFailure(systemLayer.SetCallback(mReadWatch, Confirm, reinterpret_cast<intptr_t>(this)));
    ReturnErrorOnFailure(systemLayer.RequestCallbackOnPendingRead(mReadWatch));

    return CHIP_NO_ERROR;
}

void WakeEvent::Close(LayerSockets & systemLayer)
{
    systemLayer.StopWatchingSocket(&mReadWatch);
    VerifyOrDie(::close(mReadFD) == 0);
    VerifyOrDie(::close(mWriteFD) == 0);
    mReadFD  = -1;
    mWriteFD = -1;
}

void WakeEvent::Confirm() const
{
    uint8_t buffer[128];
    ssize_t res;

    do
    {
        res = ::read(mReadFD, buffer, sizeof(buffer));
        if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
        {
            ChipLogError(chipSystemLayer, "System wake event confirm failed: %" CHIP_ERROR_FORMAT,
                         CHIP_ERROR_POSIX(errno).Format());
            return;
        }
    } while (res == sizeof(buffer));
}

CHIP_ERROR WakeEvent::Notify() const
{
    char byte = 1;

    if (::write(mWriteFD, &byte, 1) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
    {
        return CHIP_ERROR_POSIX(errno);
    }

    return CHIP_NO_ERROR;
}

#else // CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE

CHIP_ERROR WakeEvent::Open(LayerSockets & systemLayer)
{
    mReadFD = ::eventfd(0, 0);
    if (mReadFD == -1)
    {
        return CHIP_ERROR_POSIX(errno);
    }

    ReturnErrorOnFailure(systemLayer.StartWatchingSocket(mReadFD, &mReadWatch));
    ReturnErrorOnFailure(systemLayer.SetCallback(mReadWatch, Confirm, reinterpret_cast<intptr_t>(this)));
    ReturnErrorOnFailure(systemLayer.RequestCallbackOnPendingRead(mReadWatch));

    return CHIP_NO_ERROR;
}

void WakeEvent::Close(LayerSockets & systemLayer)
{
    systemLayer.StopWatchingSocket(&mReadWatch);
    VerifyOrDie(::close(mReadFD) == 0);
    mReadFD = -1;
}

void WakeEvent::Confirm() const
{
    uint64_t value;

    if (::read(mReadFD, &value, sizeof(value)) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
    {
        ChipLogError(chipSystemLayer, "System wake event confirm failed: %" CHIP_ERROR_FORMAT, CHIP_ERROR_POSIX(errno).Format());
    }
}

CHIP_ERROR WakeEvent::Notify() const
{
    uint64_t value = 1;

    if (::write(mReadFD, &value, sizeof(value)) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
    {
        return CHIP_ERROR_POSIX(errno);
    }

    return CHIP_NO_ERROR;
}

#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE

} // namespace System
} // namespace chip

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
