/*
 *
 *    Copyright 2016-2018 The nlfaultinjection 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
 *      Implementation of the fault-injection utilities.
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#include <nlassert.h>

#include <nlfaultinjection.hpp>

namespace nl {

namespace FaultInjection {

static void Die(void) __attribute__((noreturn));

static GlobalContext *sGlobalContext = NULL;

/**
 * The callback function that implements the deterministic
 * injection feature (see FailAtFault).
 */
static bool DeterministicCbFn(Identifier aId,
                              Record *aRecord,
                              void *aContext)
{
    bool retval = false;

    (void)aId;
    (void)aContext;

    if (aRecord->mNumCallsToSkip)
    {
        aRecord->mNumCallsToSkip--;
    }
    else if (aRecord->mNumCallsToFail)
    {
        aRecord->mNumCallsToFail--;
        retval = true;
    }

    return retval;
}

/**
 * Callback list node for DeterministicCbFn.
 * This node terminates all callback lists.
 */
static Callback sDeterministicCb = { DeterministicCbFn, NULL, NULL };

/**
 * The callback function that implements the random
 * injection feature (see FailRandomlyAtFault).
 */
static bool RandomCbFn(Identifier aId,
                       Record *aRecord,
                       void *aContext)
{
    bool retval = false;

    (void)aId;
    (void)aContext;

    if (aRecord->mPercentage > 0)
    {
        int randValue = (rand() % 100) + 1;
        if (randValue <= aRecord->mPercentage)
        {
            retval = true;
        }
    }

    return retval;
}

/**
 * Callback list node for RandomCbFn.
 * Note that this is initialized to point to sDeterministicCb.
 * All Record instances are initialized to point to
 * this callback node.
 */
static Callback sRandomCb = { RandomCbFn, NULL, &sDeterministicCb };

/**
 * Alias for the address of the first default callback.
 */
static const Callback *sEndOfCustomCallbacks = &sRandomCb;

/**
 * Initialize the Manager instance.
 *
 * @param[in]   inNumFaults     The size of inFaultArray, equal to the number of fault IDs.
 * @param[in]   inFaultArray    A pointer to an array of Record, in which this object
 *                              will store the configuration of each fault.
 * @param[in]   inManagerName   A pointer to a C string containing the name of the Manager.
 * @param[in]   inFaultNames    A pointer to an array of inNumFaults C strings that describe
 *                              each fault ID.
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::Init(size_t inNumFaults,
                      Record *inFaultArray,
                      Name inManagerName,
                      const Name *inFaultNames)
{
    int32_t err = 0;
    Identifier i;

    nlEXPECT_ACTION((inNumFaults > 0 && inFaultArray && inManagerName && inFaultNames), exit, err = -EINVAL);

    mName = inManagerName;
    mNumFaults = inNumFaults;
    mFaultRecords = inFaultArray;
    mFaultNames = inFaultNames;
    mLock = NULL;
    mUnlock = NULL;
    mLockContext = NULL;

    // Link all callback lists to the two default callbacks.
    for (i = 0; i < mNumFaults; i++)
    {
        mFaultRecords[i].mCallbackList = &sRandomCb;
    }

exit:
    return err;
}

/**
 * Configure a fault to be triggered randomly, with a given probability defined as a percentage
 * This is meant to be used on live systems to generate a build that will encounter random failures.
 *
 * @param[in]   inId            The fault ID
 * @param[in]   inPercentage    An integer between 0 and 100. 100 means "always". 0 means "never".
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::FailRandomlyAtFault(Identifier inId,
                                     uint8_t inPercentage)
{
    int32_t err = 0;

    nlEXPECT_ACTION((inId < mNumFaults && inPercentage <= 100),
                    exit,
                    err = -EINVAL);

    Lock();

    mFaultRecords[inId].mNumCallsToSkip = 0;
    mFaultRecords[inId].mNumCallsToFail = 0;
    mFaultRecords[inId].mPercentage = inPercentage;

    Unlock();

exit:
    return err;
}

/**
 * Configure a fault to be triggered deterministically.
 *
 * @param[in]   inId                The fault ID
 * @param[in]   inNumCallsToSkip    The number of times this fault is to be skipped before it
 *                                  starts to fail.
 * @param[in]   inNumCallsToFail    The number of times the fault should be triggered.
 * @param[in]   inTakeMutex         By default this method takes the Manager's mutex.
 *                                  If inTakeMutex is set to kMutexDoNotTake, the mutex is not taken.
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::FailAtFault(Identifier inId,
                             uint32_t inNumCallsToSkip,
                             uint32_t inNumCallsToFail,
                             bool inTakeMutex)
{
    int32_t err = 0;

    nlEXPECT_ACTION(inId < mNumFaults && inNumCallsToSkip <= UINT16_MAX && inNumCallsToFail <= UINT16_MAX, exit, err = -EINVAL);

    if (inTakeMutex)
    {
        Lock();
    }

    mFaultRecords[inId].mNumCallsToSkip = static_cast<uint16_t>(inNumCallsToSkip);
    mFaultRecords[inId].mNumCallsToFail = static_cast<uint16_t>(inNumCallsToFail);
    mFaultRecords[inId].mPercentage = 0;

    if (inTakeMutex)
    {
        Unlock();
    }

exit:
    return err;
}

/**
 * @overload int32_t FailAtFault(Identifier inId, uint32_t inNumCallsToSkip, uint32_t inNumCallsToFail, bool inTakeMutex)
 */
int32_t Manager::FailAtFault(Identifier inId,
                             uint32_t inNumCallsToSkip,
                             uint32_t inNumCallsToFail)
{
    return FailAtFault(inId, inNumCallsToSkip, inNumCallsToFail, kMutexTake);
}

/**
 * Configure a fault to reboot the system when triggered.
 * If the application has installed a RebootCallbackFn, it will
 * be invoked when fault inId is triggered.
 * If the application has not installed the callback, the system
 * will crash.
 *
 * @param[in]   inId                The fault ID
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::RebootAtFault(Identifier inId)
{
    int32_t err = 0;

    nlEXPECT_ACTION(inId < mNumFaults, exit, err = -EINVAL);

    Lock();

    mFaultRecords[inId].mReboot = true;

    Unlock();

exit:
    return err;
}

/**
 * Store a set of arguments for a given fault ID.
 * The array of arguments is made available to the code injected with
 * the nlFAULT_INJECT macro.
 * For this to work for a given fault ID, the Manager must allocate memory to
 * store the arguments and configure the Record's mLengthOfArguments and
 * mArguments members accordingly.
 *
 * @param[in]   inId                The fault ID
 * @param[in]   inNumArgs           The number of arguments in the array pointed to by inArgs.
 * @param[in]   inArgs              The pointer to the array of integers to be stored in the fault
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::StoreArgsAtFault(Identifier inId, uint16_t inNumArgs, int32_t *inArgs)
{
    int32_t err = 0;
    size_t i;

    nlEXPECT_ACTION(inId < mNumFaults &&
                    mFaultRecords[inId].mArguments != NULL &&
                    mFaultRecords[inId].mLengthOfArguments >= inNumArgs &&
                    inNumArgs <= UINT8_MAX,
                    exit,
                    err = -EINVAL);

    Lock();

    for (i = 0; i < inNumArgs; i++)
    {
        mFaultRecords[inId].mArguments[i] = inArgs[i];
    }

    mFaultRecords[inId].mNumArguments = static_cast<uint8_t>(inNumArgs);

    Unlock();

exit:
    return err;
}

/**
 * Attach a callback to a fault ID.
 * Calling this twice does not attach the callback twice.
 *
 * @param[in]   inId        The fault ID
 * @param[in]   inCallback  The callback node to be attached to the fault
 *
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::InsertCallbackAtFault(Identifier inId,
                                       Callback *inCallBack)
{
    int32_t err = 0;

    // Make sure it's not already there
    err = RemoveCallbackAtFault(inId, inCallBack);

    nlEXPECT_SUCCESS(err, exit);

    Lock();

    // Insert the callback at the beginning of the list.
    // Remember that all lists end into the two default (deterministic
    // and random) callbacks!
    inCallBack->mNext = mFaultRecords[inId].mCallbackList;
    mFaultRecords[inId].mCallbackList = inCallBack;

    Unlock();

exit:
    return err;
}

/**
 * Detaches a callback from a fault.
 *
 * @param[in]   inId        The fault
 * @param[in]   inCallback  The callback node to be removed.
 * @param[in]   inTakeMutex         By default this method takes the Manager's mutex.
 *                                  If inTakeMutex is set to kMutexDoNotTake, the mutex is not taken.
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::RemoveCallbackAtFault(Identifier inId,
                                       Callback *inCallBack,
                                       bool inTakeMutex)
{
    int32_t err = 0;
    Callback **cb = NULL;

    nlEXPECT_ACTION((inId < mNumFaults) && (inCallBack != NULL), exit, err = -EINVAL);

    if (inTakeMutex)
    {
        Lock();
    }

    cb = &mFaultRecords[inId].mCallbackList;

    while (*cb != NULL)
    {
        if (*cb == inCallBack)
        {
            *cb = (*cb)->mNext;
            break;
        }
        cb = &((*cb)->mNext);
    }

    if (inTakeMutex)
    {
        Unlock();
    }

exit:
    return err;
}

/**
 * @overload int32_t Manager::RemoveCallbackAtFault(Identifier inId, Callback *inCallBack, bool inTakeMutex)
 */
int32_t Manager::RemoveCallbackAtFault(Identifier inId,
                                       Callback *inCallBack)
{
    return RemoveCallbackAtFault(inId, inCallBack, kMutexTake);
}

/**
 * When the program traverses the location at which a fault should be injected, this method is invoked
 * on the manager to query the configuration of the fault ID.
 *
 * A fault can be triggered randomly, deterministically or on a call-by-call basis by a callback.
 * All three types of trigger can be installed at the same time, and they all get a chance of
 * injecting the fault.
 *
 * @param[in] inId                The fault ID
 * @param[in] inTakeMutex         By default this method takes the Manager's mutex.
 *                                If inTakeMutex is set to kMutexDoNotTake, the mutex is not taken.
 *
 * @return    true if the fault should be injected; false otherwise.
 */
bool Manager::CheckFault(Identifier inId, bool inTakeMutex)
{
    bool retval = false;
    Callback *cb = NULL;
    Callback *next = NULL;
    bool reboot = false;

    nlEXPECT(inId < mNumFaults, exit);

    if (inTakeMutex)
    {
        Lock();
    }

    cb = mFaultRecords[inId].mCallbackList;

    while (cb != NULL)
    {
        // Save mNext now, in case the callback removes itself
        // calling RemoveCallbackAtFault
        next = cb->mNext;
        if (cb->mCallBackFn(inId, &mFaultRecords[inId], cb->mContext))
        {
            retval = true;
        }
        cb = next;
    }

    reboot = mFaultRecords[inId].mReboot;

    if (retval && sGlobalContext && sGlobalContext->mCbTable.mPostInjectionCb)
    {
        sGlobalContext->mCbTable.mPostInjectionCb(this, inId, &mFaultRecords[inId]);
    }

    if (retval && reboot)
    {
        // If the application has not setup a context and/or reboot callback, the system will crash
        if (sGlobalContext && sGlobalContext->mCbTable.mRebootCb)
        {
            sGlobalContext->mCbTable.mRebootCb();
        }
        else
        {
            Die();
        }
    }

    mFaultRecords[inId].mNumTimesChecked++;

    if (inTakeMutex)
    {
        Unlock();
    }

exit:
    return retval;
}

/**
 * @overload bool CheckFault(Identifier inId, bool inTakeMutex)
 */
bool Manager::CheckFault(Identifier inId)
{
    return CheckFault(inId, kMutexTake);
}

/**
 * When the program traverses the location at which a fault should be injected, this method is invoked
 * on the manager to query the configuration of the fault ID.
 *
 * This version of the method retrieves the arguments stored in the Record.
 *
 * A fault can be triggered randomly, deterministically or on a call-by-call basis by a callback.
 * All three types of trigger can be installed at the same time, and they all get a chance of
 * injecting the fault.
 *
 * @param[in] inId            The fault ID
 * @param[in] outNumArgs      The length of the array pointed to by outArgs
 * @param[in] outArgs         The array of arguments configured for the faultId
 * @param[in] inTakeMutex     By default this method takes the Manager's mutex.
 *                            If inTakeMutex is set to kMutexDoNotTake, the mutex is not taken.
 *
 * @return    true if the fault should be injected; false otherwise.
 */
bool Manager::CheckFault(Identifier inId, uint16_t &outNumArgs, int32_t *&outArgs, bool inTakeMutex)
{
    bool retval = false;

    if (inTakeMutex)
    {
        Lock();
    }

    retval = CheckFault(inId, kMutexDoNotTake);
    if (retval)
    {
        outNumArgs = mFaultRecords[inId].mNumArguments;
        outArgs = mFaultRecords[inId].mArguments;
    }

    if (inTakeMutex)
    {
        Unlock();
    }

    return retval;
}

/**
 * @overload bool CheckFault(Identifier inId, uint16_t &outNumArgs, int32_t *&outArgs, bool inTakeMutex)
 */
bool Manager::CheckFault(Identifier inId, uint16_t &outNumArgs, int32_t *&outArgs)
{
    return CheckFault(inId, outNumArgs, outArgs, kMutexTake);
}

/**
 * Reset the counters in the fault Records
 * Note that calling this method does not impact the current configuration
 * in any way (including the number of times a fault is to be skipped
 * before it should fail).
 */
void Manager::ResetFaultCounters(void)
{
    Identifier id = 0;

    Lock();

    for (id = 0; id < mNumFaults; id++)
    {
        mFaultRecords[id].mNumTimesChecked = 0;
    }

    Unlock();
}

/**
 * Reset the configuration of a fault Record
 *
 * @param[in] inId        The fault ID
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::ResetFaultConfigurations(Identifier inId)
{
    Callback *cb;
    int32_t err = 0;

    nlEXPECT_ACTION((inId < mNumFaults),
                    exit,
                    err = -EINVAL);

    Lock();

    mFaultRecords[inId].mNumCallsToSkip = 0;
    mFaultRecords[inId].mNumCallsToFail = 0;
    mFaultRecords[inId].mPercentage = 0;
    mFaultRecords[inId].mReboot = 0;
    mFaultRecords[inId].mNumArguments = 0;

    cb = mFaultRecords[inId].mCallbackList;
    // All callback handling code in this module is based on the assumption
    // that custom callbacks are inserted at the beginning of the list
    while (cb != sEndOfCustomCallbacks && cb != NULL)
    {
        (void)RemoveCallbackAtFault(inId, cb, kMutexDoNotTake);
        cb = mFaultRecords[inId].mCallbackList;
    }

    Unlock();

exit:
    return err;
}

/**
 * Reset the configuration of all fault Records
 *
 * @return      -EINVAL if the inputs are not valid.
 *              0 otherwise.
 */
int32_t Manager::ResetFaultConfigurations(void)
{
    int32_t err = 0;
    Identifier id = 0;

    for (id = 0; id < mNumFaults; id++)
    {
        err = ResetFaultConfigurations(id);
        nlEXPECT(err == 0, exit);
    }

exit:
    return err;
}

/**
 * Take the Manager's mutex.
 */
void Manager::Lock(void)
{
    if (mLock)
    {
        mLock(mLockContext);
    }
}

/**
 * Release the Manager's mutex.
 */
void Manager::Unlock(void)
{
    if (mUnlock)
    {
        mUnlock(mLockContext);
    }
}

/**
 * Configure the instance of GlobalContext to use.
 * On systems in which faults are configured and injected from different threads,
 * this function should be called before threads are started.
 *
 * @param[in] inGlobalContext   Pointer to the GlobalContext provided by the application
 */
void SetGlobalContext(GlobalContext *inGlobalContext)
{
    sGlobalContext = inGlobalContext;
}

/**
 * Parse an integer
 *
 * This implementation does not check for ERANGE, as it assumes a very simple
 * underlying implementation of strtol.
 *
 * @param[in]  str      Pointer to a string representing an integer
 *
 * @param[out] num      Pointer to the integer result
 *
 * @return              true in case of success; false if the string does not
 *                      contain an integer.
 */
static bool ParseInt(const char *str, int32_t *num)
{
    char *endptr = NULL;
    long tmp;
    bool retval = true;

    tmp = strtol(str, &endptr, 10);
    if (!endptr || *endptr != '\0')
    {
        retval = false;
    }
    else
    {
        *num = static_cast<int32_t>(tmp);
    }

    return retval;
}

/**
 * Parse an unsigned integer
 *
 * @param[in]  str      Pointer to a string representing an insigned int
 *
 * @param[out] num      Pointer to the unsigned integer result
 *
 * @return              true in case of success; false if the string does not
 *                      contain an unsigned integer.
 */
static bool ParseUInt(const char *str, uint32_t *num)
{
    bool retval = true;
    int32_t tmpint = 0;

    retval = ParseInt(str, &tmpint);
    if (retval)
    {
        if (tmpint < 0)
        {
            retval = false;
        }
        else
        {
            *num = static_cast<uint32_t>(tmpint);
        }
    }

    return retval;
}

/**
 * Parse a fault-injection configuration string and apply the configuration.
 *
 * @param[in]   aFaultInjectionStr  The configuration string. An example of a valid string that
 *                                  enables two faults is "system_buffer_f5_s1:inet_send_p33"
 *                                  An example of a configuration string that
 *                                  also passes three integer arguments to the fault point is
 *                                  "system_buffer_f5_s1_a10_a7_a-4"
 *                                  The format is
 *                                  "<module>_<fault>_{f<numTimesToFail>[_s<numTimesToSkip>],p<randomFailurePercentage>}[_a<integer>]..."
 *
 * @param[in]   inArray             An array of GetManagerFn callbacks
 *                                  to be used to parse the string.
 *
 * @param[in]   inArraySize         Num of elements in inArray
 *
 * @return      true  if the string can be parsed completely; false otherwise
 */
bool ParseFaultInjectionStr(char *aFaultInjectionStr, const GetManagerFn *inArray, size_t inArraySize)
{
    ManagerTable table = { inArray, inArraySize };
    size_t numTables = 1;

    return ParseFaultInjectionStr(aFaultInjectionStr, &table, numTables);
}

/**
 * Parse a fault-injection configuration string and apply the configuration.
 *
 * @param[in]   aFaultInjectionStr  The configuration string. An example of a valid string that
 *                                  enables two faults is "system_buffer_f5_s1:inet_send_p33"
 *                                  An example of a configuration string that
 *                                  also passes three integer arguments to the fault point is
 *                                  "system_buffer_f5_s1_a10_a7_a-4"
 *                                  The format is
 *                                  "<module>_<fault>_{f<numTimesToFail>[_s<numTimesToSkip>],p<randomFailurePercentage>}[_a<integer>]..."
 *
 * @param[in]   inTables            An array of ManagerTable structures
 *                                  to be used to parse the string.
 *
 * @param[in]   inNumTables         Size of inTables
 *
 * @return      true  if the string can be parsed completely; false otherwise
 */
bool ParseFaultInjectionStr(char *aFaultInjectionStr, const ManagerTable *inTables, size_t inNumTables)
{
    char *tok1 = NULL;
    char *savePtr1 = NULL;
    char *tok2 = NULL;
    char *savePtr2 = NULL;
    char *outerString = aFaultInjectionStr;
    size_t i = 0;
    nl::FaultInjection::Identifier j = 0;
    int err = 0;
    bool retval = false;
    int32_t args[kMaxFaultArgs];
    uint16_t numArgs = 0;

    nl::FaultInjection::Manager *mgr = NULL;
    nl::FaultInjection::Identifier faultId = 0;

    memset(args, 0, sizeof(args));

    while ((tok1 = strtok_r(outerString, ":", &savePtr1)))
    {
        uint32_t numTimesToFail = 0;
        uint32_t numTimesToSkip = 0;
        uint32_t percentage = 0;
        bool gotPercentage = false;
        bool gotReboot = false;
        bool gotArguments = false;
        const Name *faultNames = NULL;

        outerString = NULL;

        tok2 = strtok_r(tok1, "_", &savePtr2);
        nlEXPECT(tok2 != NULL, exit);

		// this is the module
		for (i = 0; i < inNumTables; i++)
        {
            for (j = 0; j < inTables[i].mNumItems; j++)
            {
                nl::FaultInjection::Manager &tmpMgr = inTables[i].mArray[j]();
                if (!strcmp(tok2, tmpMgr.GetName()))
                {
                    mgr = &tmpMgr;
                    break;
                }
            }
        }
        nlEXPECT(mgr != NULL, exit);

        tok2 = strtok_r(NULL, "_", &savePtr2);
        nlEXPECT(tok2 != NULL, exit);

        // this is the fault name
        faultNames = mgr->GetFaultNames();
		for (j = 0; j < mgr->GetNumFaults(); j++)
		{
			if (!strcmp(tok2, faultNames[j]))
			{
				faultId = j;
				break;
			}
		}

        nlEXPECT(j != mgr->GetNumFaults(), exit);

        while ((tok2 = strtok_r(NULL, "_", &savePtr2)))
        {
            switch (tok2[0])
            {
                case 'a':
                    {
                        int32_t tmp = 0;
                        nlEXPECT(numArgs < kMaxFaultArgs, exit);

                        gotArguments = true;

                        nlEXPECT(ParseInt(&(tok2[1]), &tmp), exit);
                        args[numArgs++] = tmp;
                    }
                    break;
                case 'f':
                    nlEXPECT(ParseUInt(&(tok2[1]), &numTimesToFail), exit);
                    break;
                case 's':
                    nlEXPECT(ParseUInt(&(tok2[1]), &numTimesToSkip), exit);
                    break;
                case 'p':
                    gotPercentage = true;
                    nlEXPECT(ParseUInt(&(tok2[1]), &percentage), exit);
                    nlEXPECT(percentage <= 100, exit);
                    break;
                case 'r':
                    gotReboot = true;
                    break;
                default:
                    goto exit;
                    break;
            }
        }

        if (gotArguments)
        {
            err = mgr->StoreArgsAtFault(faultId, numArgs, args);
            nlEXPECT_SUCCESS(err, exit);
        }

        if (gotPercentage)
        {
            err = mgr->FailRandomlyAtFault(faultId, static_cast<uint8_t>(percentage));
            nlEXPECT_SUCCESS(err, exit);
        }
        else
        {
            err = mgr->FailAtFault(faultId, numTimesToSkip, numTimesToFail);
            nlEXPECT_SUCCESS(err, exit);
        }
        if (gotReboot)
        {
            err = mgr->RebootAtFault(faultId);
            nlEXPECT_SUCCESS(err, exit);
        }
    }

    retval = true;

exit:
    return retval;
}

/**
 * Internal function to kill the process if a
 * fault is supposed to reboot the process but the application
 * has not installed a callback
 */
static void Die(void)
{
    while (true)
        *((volatile long *)1) = 0;
}

} // namespace FaultInjection

} // namespace nl
