/*
 * 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 <string.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) {
        ALOG(LOG_ERROR, logCatTag, "%s", line);
    } else {
        ALOG(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);
    }
}
