/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * @brief
 *   This file includes the platform-specific initializers.
 */

#include "platform-posix.h"

#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <openthread/tasklet.h>
#include <openthread/platform/alarm-milli.h>

uint64_t gNodeId = 0;

extern bool gPlatformPseudoResetWasRequested;

static void PrintUsage(const char *aArg0)
{
    fprintf(stderr, "Syntax:\n    %s [-s TimeSpeedUpFactor] {NodeId|Device DeviceConfig|Command CommandArgs}\n", aArg0);
    exit(EXIT_FAILURE);
}

void otSysInit(int aArgCount, char *aArgVector[])
{
    int         i;
    uint32_t    speedUpFactor = 1;
    char *      endptr;
    const char *radioFile   = NULL;
    const char *radioConfig = "";

    if (gPlatformPseudoResetWasRequested)
    {
        gPlatformPseudoResetWasRequested = false;
        return;
    }

    if (aArgCount < 2)
    {
        PrintUsage(aArgVector[0]);
    }

    i = 1;
    if (!strcmp(aArgVector[i], "-s"))
    {
        ++i;
        speedUpFactor = (uint32_t)strtol(aArgVector[i], &endptr, 0);

        if (*endptr != '\0' || speedUpFactor == 0)
        {
            fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[i]);
            exit(EXIT_FAILURE);
        }
        ++i;
    }

    if (i >= aArgCount)
    {
        PrintUsage(aArgVector[0]);
    }

    radioFile = aArgVector[i];
    if (i + 1 < aArgCount)
    {
        radioConfig = aArgVector[i + 1];
    }

    platformLoggingInit(basename(aArgVector[0]));

#if OPENTHREAD_POSIX_VIRTUAL_TIME
    otSimInit();
#endif
    platformAlarmInit(speedUpFactor);
    platformRadioInit(radioFile, radioConfig);
    platformRandomInit();
#if OPENTHREAD_ENABLE_PLATFORM_UDP
    platformUdpInit();
#endif
}

bool otSysPseudoResetWasRequested(void)
{
    return gPlatformPseudoResetWasRequested;
}

void otSysDeinit(void)
{
#if OPENTHREAD_POSIX_VIRTUAL_TIME
    otSimDeinit();
#endif
    platformRadioDeinit();
}

#if OPENTHREAD_POSIX_VIRTUAL_TIME
/**
 * This function try selecting the given file descriptors in nonblocking mode.
 *
 * @param[inout]    aReadFdSet   A pointer to the read file descriptors.
 * @param[inout]    aWriteFdSet  A pointer to the write file descriptors.
 * @param[inout]    aErrorFdSet  A pointer to the error file descriptors.
 * @param[in]       aMaxFd       The max file descriptor.
 *
 * @returns The value returned from select().
 *
 */
static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int aMaxFd)
{
    struct timeval timeout          = {0, 0};
    fd_set         originReadFdSet  = *aReadFdSet;
    fd_set         originWriteFdSet = *aWriteFdSet;
    fd_set         originErrorFdSet = *aErrorFdSet;
    int            rval;

    rval = select(aMaxFd + 1, aReadFdSet, aWriteFdSet, aErrorFdSet, &timeout);

    if (rval == 0)
    {
        *aReadFdSet  = originReadFdSet;
        *aWriteFdSet = originWriteFdSet;
        *aErrorFdSet = originErrorFdSet;
    }

    return rval;
}
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME

void otSysProcessDrivers(otInstance *aInstance)
{
    fd_set         readFdSet;
    fd_set         writeFdSet;
    fd_set         errorFdSet;
    struct timeval timeout;
    int            maxFd = -1;
    int            rval;

    FD_ZERO(&readFdSet);
    FD_ZERO(&writeFdSet);
    FD_ZERO(&errorFdSet);

    platformAlarmUpdateTimeout(&timeout);
    platformUartUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd);
#if OPENTHREAD_ENABLE_PLATFORM_UDP
    platformUdpUpdateFdSet(aInstance, &readFdSet, &maxFd);
#endif
#if OPENTHREAD_POSIX_VIRTUAL_TIME
    otSimUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd, &timeout);
#else
    platformRadioUpdateFdSet(&readFdSet, &writeFdSet, &maxFd, &timeout);
#endif

    if (otTaskletsArePending(aInstance))
    {
        timeout.tv_sec  = 0;
        timeout.tv_usec = 0;
    }

#if OPENTHREAD_POSIX_VIRTUAL_TIME
    if (timerisset(&timeout))
    {
        // Make sure there are no data ready in UART
        rval = trySelect(&readFdSet, &writeFdSet, &errorFdSet, maxFd);

        if (rval == 0)
        {
            bool noWrite = true;

            // If there are write requests, the device is supposed to wake soon
            for (int i = 0; i < maxFd + 1; ++i)
            {
                if (FD_ISSET(i, &writeFdSet))
                {
                    noWrite = false;
                    break;
                }
            }

            if (noWrite)
            {
                otSimSendSleepEvent(&timeout);
            }

            rval = select(maxFd + 1, &readFdSet, &writeFdSet, &errorFdSet, NULL);
            assert(rval > 0);
        }
    }
    else
#endif
    {
        rval = select(maxFd + 1, &readFdSet, &writeFdSet, &errorFdSet, &timeout);
    }

    if ((rval < 0) && (errno != EINTR))
    {
        perror("select");
        exit(EXIT_FAILURE);
    }

#if OPENTHREAD_POSIX_VIRTUAL_TIME
    otSimProcess(aInstance, &readFdSet, &writeFdSet, &errorFdSet);
#else
    platformRadioProcess(aInstance, &readFdSet, &writeFdSet);
#endif
    platformUartProcess(&readFdSet, &writeFdSet, &errorFdSet);
    platformAlarmProcess(aInstance);
#if OPENTHREAD_ENABLE_PLATFORM_UDP
    platformUdpProcess(aInstance, &readFdSet);
#endif
}
