/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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 <testUtil.h>

#include <assert.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <sys/time.h>
#include <sys/wait.h>

#include <cutils/log.h>

#define ALEN(a) (sizeof(a) / sizeof(a [0]))  // Array length
typedef unsigned int bool_t;
#define true (0 == 0)
#define false (!true)

#define MAXSTR 200

static const char *logCatTag;
static const unsigned int uSecsPerSec = 1000000;
static const unsigned int nSecsPerSec = 1000000000;

// struct timespec to double
double ts2double(const struct timespec *val)
{
    double rv;

    rv = val->tv_sec;
    rv += (double) val->tv_nsec / nSecsPerSec;

    return rv;
}

// struct timeval to double
double tv2double(const struct timeval *val)
{
    double rv;

    rv = val->tv_sec;
    rv += (double) val->tv_usec / uSecsPerSec;

    return rv;
}

// double to struct timespec
struct timespec double2ts(double amt)
{
    struct timespec rv;

    rv.tv_sec = floor(amt);
    rv.tv_nsec = (amt - rv.tv_sec) * nSecsPerSec;
    // TODO: Handle cases where amt is negative
    while ((unsigned) rv.tv_nsec >= nSecsPerSec) {
        rv.tv_nsec -= nSecsPerSec;
        rv.tv_sec++;
    }

    return rv;
}

// double to struct timeval
struct timeval double2tv(double amt)
{
    struct timeval rv;

    rv.tv_sec = floor(amt);
    rv.tv_usec = (amt - rv.tv_sec) * uSecsPerSec;
    // TODO: Handle cases where amt is negative
    while ((unsigned) rv.tv_usec >= uSecsPerSec) {
        rv.tv_usec -= uSecsPerSec;
        rv.tv_sec++;
    }

    return rv;
}

// Delta (difference) between two struct timespec.
// It is expected that the time given by the structure pointed to by
// second, is later than the time pointed to by first.
struct timespec tsDelta(const struct timespec *first,
                        const struct timespec *second)
{
    struct timespec rv;

    assert(first != NULL);
    assert(second != NULL);
    assert(first->tv_nsec >= 0 && first->tv_nsec < nSecsPerSec);
    assert(second->tv_nsec >= 0 && second->tv_nsec < nSecsPerSec);
    rv.tv_sec = second->tv_sec - first->tv_sec;
    if (second->tv_nsec >= first->tv_nsec) {
        rv.tv_nsec = second->tv_nsec - first->tv_nsec;
    } else {
        rv.tv_nsec = (second->tv_nsec + nSecsPerSec) - first->tv_nsec;
        rv.tv_sec--;
    }

    return rv;
}

// Delta (difference) between two struct timeval.
// It is expected that the time given by the structure pointed to by
// second, is later than the time pointed to by first.
struct timeval tvDelta(const struct timeval *first,
                       const struct timeval *second)
{
    struct timeval rv;

    assert(first != NULL);
    assert(second != NULL);
    assert(first->tv_usec >= 0 && first->tv_usec < uSecsPerSec);
    assert(second->tv_usec >= 0 && second->tv_usec < uSecsPerSec);
    rv.tv_sec = second->tv_sec - first->tv_sec;
    if (second->tv_usec >= first->tv_usec) {
        rv.tv_usec = second->tv_usec - first->tv_usec;
    } else {
        rv.tv_usec = (second->tv_usec + uSecsPerSec) - first->tv_usec;
        rv.tv_sec--;
    }

    return rv;
}

void testPrint(FILE *stream, const char *fmt, ...)
{
    char line[MAXSTR];
    va_list args;

    va_start(args, fmt);
    vsnprintf(line, sizeof(line), fmt, args);
    if (stream == stderr) {
        LOG(LOG_ERROR, logCatTag, "%s", line);
    } else {
        LOG(LOG_INFO, logCatTag, "%s", line);
    }
    vfprintf(stream, fmt, args);
    fputc('\n', stream);
}

// Set tag used while logging to the logcat error interface
void testSetLogCatTag(const char *tag)
{
    logCatTag = tag;
}

// Obtain pointer to current log to logcat error interface tag
const char * testGetLogCatTag(void)
{
    return logCatTag;
}

/*
 * Random
 *
 * Returns a pseudo random number in the range [0:2^32-1].
 *
 * Precondition: srand48() called to set the seed of
 *   the pseudo random number generator.
 */
uint32_t testRand(void)
{
    uint32_t val;

    // Use lrand48() to obtain 31 bits worth
    // of randomness.
    val = lrand48();

    // Make an additional lrand48() call and merge
    // the randomness into the most significant bits.
    val ^= lrand48() << 1;

    return val;
}

/*
 * Random Modulus
 *
 * Pseudo randomly returns unsigned integer in the range [0, mod).
 *
 * Precondition: srand48() called to set the seed of
 *   the pseudo random number generator.
 */
uint32_t testRandMod(uint32_t mod)
{
    // Obtain the random value
    // Use lrand48() when it would produce a sufficient
    // number of random bits, otherwise use testRand().
    const uint32_t lrand48maxVal = ((uint32_t) 1 << 31) - 1;
    uint32_t val = (mod <= lrand48maxVal) ? (uint32_t) lrand48() : testRand();

    /*
     * The contents of individual bytes tend to be less than random
     * across different seeds.  For example, srand48(x) and
     * srand48(x + n * 4) cause lrand48() to return the same sequence of
     * least significant bits.  For small mod values this can produce
     * noticably non-random sequnces.  For mod values of less than 2
     * bytes, will use the randomness from all the bytes.
     */
    if (mod <= 0x10000) {
        val = (val & 0xffff) ^ (val >> 16);

        // If mod less than a byte, can further combine down to
        // a single byte.
        if (mod <= 0x100) {
            val = (val & 0xff) ^ (val >> 8);
        }
    }

    return val % mod;
}

/*
 * Random Boolean
 *
 * Pseudo randomly returns 0 (false) or 1 (true).
 *
 * Precondition: srand48() called to set the seed of
 *   the pseudo random number generator.
 */
int testRandBool(void)
{
    return (testRandMod(2));
}

/*
 * Random Fraction
 *
 * Pseudo randomly return a value in the range [0.0, 1.0).
 *
 * Precondition: srand48() called to set the seed of
 *   the pseudo random number generator.
 */
double testRandFract(void)
{
    return drand48();
}

// Delays for the number of seconds specified by amt or a greater amount.
// The amt variable is of type float and thus non-integer amounts
// of time can be specified.  This function automatically handles cases
// where nanosleep(2) returns early due to reception of a signal.
void testDelay(float amt)
{
    struct timespec   start, current, delta;
    struct timespec   remaining;

    // Get the time at which we started
    clock_gettime(CLOCK_MONOTONIC, &start);

    do {
        // Get current time
        clock_gettime(CLOCK_MONOTONIC, &current);

        // How much time is left
        delta = tsDelta(&start, &current);
        if (ts2double(&delta) > amt) { break; }

        // Request to sleep for the remaining time
        remaining = double2ts(amt - ts2double(&delta));
        (void) nanosleep(&remaining, NULL);
    } while (true);
}

// Delay spins for the number of seconds specified by amt or a greater
// amount.  The amt variable is of type float and thus non-integer amounts
// of time can be specified.  Differs from testDelay() in that
// testDelaySpin() performs a spin loop, instead of using nanosleep().
void testDelaySpin(float amt)
{
    struct timespec   start, current, delta;

    // Get the time at which we started
    clock_gettime(CLOCK_MONOTONIC, &start);

    do {
        // Get current time
        clock_gettime(CLOCK_MONOTONIC, &current);

        // How much time is left
        delta = tsDelta(&start, &current);
        if (ts2double(&delta) > amt) { break; }
    } while (true);
}

/*
 * Hex Dump
 *
 * Displays in hex the contents of the memory starting at the location
 * pointed to by buf, for the number of bytes given by size.
 * Each line of output is indented by a number of spaces that
 * can be set by calling xDumpSetIndent().  It is also possible
 * to offset the displayed address by an amount set by calling
 * xDumpSetOffset.
 */
static uint8_t     xDumpIndent;
static uint64_t    xDumpOffset;
void
testXDump(const void *buf, size_t size)
{
    const unsigned int bytesPerLine = 16;
    int rv;
    char line[MAXSTR];
    const unsigned char *ptr = buf, *start = buf;
    size_t num = size;
    char *linep = line;

    while (num) {
        if (((ptr - start) % bytesPerLine) == 0) {
            if (linep != line) {
                testPrintE("%s", line);
            }
            linep = line;
            rv = snprintf(linep, ALEN(line) - (linep - line),
                "%*s%06llx:", xDumpIndent, "",
                (long long) (ptr - start) + xDumpOffset);
            linep += rv;
        }

        // Check that there is at least room for 4
        // more characters.  The 4 characters being
        // a space, 2 hex digits and the terminating
        // '\0'.
        assert((ALEN(line) - 4) >= (linep - line));
        rv = snprintf(linep, ALEN(line) - (linep - line),
            " %02x", *ptr++);
        linep += rv;
        num--;
    }
    if (linep != line) {
        testPrintE("%s", line);
    }
}

// Set an indent of spaces for each line of hex dump output
void
testXDumpSetIndent(uint8_t indent)
{
    xDumpIndent = indent;
}

// Obtain the current hex dump indent amount
uint8_t
testXDumpGetIndent(void)
{
    return xDumpIndent;
}

// Set the hex dump address offset amount
void
testXDumpSetOffset(uint64_t offset)
{
    xDumpOffset = offset;
}

// Get the current hex dump address offset amount
uint64_t
testXDumpGetOffset(void)
{
    return xDumpOffset;
}

/*
 * Execute Command
 *
 * Executes the command pointed to by cmd.  Output from the
 * executed command is captured and sent to LogCat Info.  Once
 * the command has finished execution, it's exit status is captured
 * and checked for an exit status of zero.  Any other exit status
 * causes diagnostic information to be printed and an immediate
 * testcase failure.
 */
void testExecCmd(const char *cmd)
{
    FILE *fp;
    int rv;
    int status;
    char str[MAXSTR];

    // Display command to be executed
    testPrintI("cmd: %s", cmd);

    // Execute the command
    fflush(stdout);
    if ((fp = popen(cmd, "r")) == NULL) {
        testPrintE("execCmd popen failed, errno: %i", errno);
        exit(100);
    }

    // Obtain and display each line of output from the executed command
    while (fgets(str, sizeof(str), fp) != NULL) {
        if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) {
            str[strlen(str) - 1] = '\0';
        }
        testPrintI(" out: %s", str);
    }

    // Obtain and check return status of executed command.
    // Fail on non-zero exit status
    status = pclose(fp);
    if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
        testPrintE("Unexpected command failure");
        testPrintE("  status: %#x", status);
        if (WIFEXITED(status)) {
            testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status));
        }
        if (WIFSIGNALED(status)) {
            testPrintE("WTERMSIG: %i", WTERMSIG(status));
        }
        exit(101);
    }
}
