/*
 * Copyright (C) 2008 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.
 */
/*
 * Thread that reads from stdout/stderr and converts them to log messages.
 * (Sort of a hack.)
 */
#include "Dalvik.h"

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define kFilenoStdout   1
#define kFilenoStderr   2

/*
 * Hold our replacement stdout/stderr.
 */
typedef struct StdPipes {
    int stdoutPipe[2];
    int stderrPipe[2];
} StdPipes;

#define kMaxLine    512

/*
 * Hold some data.
 */
typedef struct BufferedData {
    char    buf[kMaxLine+1];
    int     count;
} BufferedData;

// fwd
static void* stdioConverterThreadStart(void* arg);
static bool readAndLog(int fd, BufferedData* data, const char* tag);


/*
 * Crank up the stdout/stderr converter thread.
 *
 * Returns immediately.
 */
bool dvmStdioConverterStartup(void)
{
    StdPipes* pipeStorage;

    gDvm.haltStdioConverter = false;

    dvmInitMutex(&gDvm.stdioConverterLock);
    pthread_cond_init(&gDvm.stdioConverterCond, NULL);

    pipeStorage = (StdPipes*) malloc(sizeof(StdPipes));
    if (pipeStorage == NULL)
        return false;

    if (pipe(pipeStorage->stdoutPipe) != 0) {
        LOGW("pipe failed: %s\n", strerror(errno));
        return false;
    }
    if (pipe(pipeStorage->stderrPipe) != 0) {
        LOGW("pipe failed: %s\n", strerror(errno));
        return false;
    }

    if (dup2(pipeStorage->stdoutPipe[1], kFilenoStdout) != kFilenoStdout) {
        LOGW("dup2(1) failed: %s\n", strerror(errno));
        return false;
    }
    close(pipeStorage->stdoutPipe[1]);
    pipeStorage->stdoutPipe[1] = -1;
#ifdef HAVE_ANDROID_OS
    /* don't redirect stderr on sim -- logs get written there! */
    /* (don't need this on the sim anyway) */
    if (dup2(pipeStorage->stderrPipe[1], kFilenoStderr) != kFilenoStderr) {
        LOGW("dup2(2) failed: %d %s\n", errno, strerror(errno));
        return false;
    }
    close(pipeStorage->stderrPipe[1]);
    pipeStorage->stderrPipe[1] = -1;
#endif


    /*
     * Create the thread.
     */
    dvmLockMutex(&gDvm.stdioConverterLock);

    if (!dvmCreateInternalThread(&gDvm.stdioConverterHandle,
                "Stdio Converter", stdioConverterThreadStart, pipeStorage))
    {
        free(pipeStorage);
        return false;
    }
    /* new thread owns pipeStorage */

    while (!gDvm.stdioConverterReady) {
        dvmWaitCond(&gDvm.stdioConverterCond, &gDvm.stdioConverterLock);
    }
    dvmUnlockMutex(&gDvm.stdioConverterLock);

    return true;
}

/*
 * Shut down the stdio converter thread if it was started.
 *
 * Since we know the thread is just sitting around waiting for something
 * to arrive on stdout, print something.
 */
void dvmStdioConverterShutdown(void)
{
    gDvm.haltStdioConverter = true;
    if (gDvm.stdioConverterHandle == 0)    // not started, or still starting
        return;

    /* print something to wake it up */
    printf("Shutting down\n");
    fflush(stdout);

    LOGD("Joining stdio converter...\n");
    pthread_join(gDvm.stdioConverterHandle, NULL);
}

/*
 * Select on stdout/stderr pipes, waiting for activity.
 *
 * DO NOT use printf from here.
 */
static void* stdioConverterThreadStart(void* arg)
{
    StdPipes* pipeStorage = (StdPipes*) arg;
    BufferedData* stdoutData;
    BufferedData* stderrData;
    int cc;

    /* tell the main thread that we're ready */
    dvmLockMutex(&gDvm.stdioConverterLock);
    gDvm.stdioConverterReady = true;
    cc = pthread_cond_signal(&gDvm.stdioConverterCond);
    assert(cc == 0);
    dvmUnlockMutex(&gDvm.stdioConverterLock);

    /* we never do anything that affects the rest of the VM */
    dvmChangeStatus(NULL, THREAD_VMWAIT);

    /*
     * Allocate read buffers.
     */
    stdoutData = (BufferedData*) malloc(sizeof(*stdoutData));
    stderrData = (BufferedData*) malloc(sizeof(*stderrData));
    stdoutData->count = stderrData->count = 0;

    /*
     * Read until shutdown time.
     */
    while (!gDvm.haltStdioConverter) {
        fd_set readfds;
        int maxFd, fdCount;

        FD_ZERO(&readfds);
        FD_SET(pipeStorage->stdoutPipe[0], &readfds);
        FD_SET(pipeStorage->stderrPipe[0], &readfds);
        maxFd = MAX(pipeStorage->stdoutPipe[0], pipeStorage->stderrPipe[0]);

        fdCount = select(maxFd+1, &readfds, NULL, NULL, NULL);

        if (fdCount < 0) {
            if (errno != EINTR) {
                LOGE("select on stdout/stderr failed\n");
                break;
            }
            LOGD("Got EINTR, ignoring\n");
        } else if (fdCount == 0) {
            LOGD("WEIRD: select returned zero\n");
        } else {
            bool err = false;
            if (FD_ISSET(pipeStorage->stdoutPipe[0], &readfds)) {
                err |= !readAndLog(pipeStorage->stdoutPipe[0], stdoutData,
                    "stdout");
            }
            if (FD_ISSET(pipeStorage->stderrPipe[0], &readfds)) {
                err |= !readAndLog(pipeStorage->stderrPipe[0], stderrData,
                    "stderr");
            }

            /* probably EOF; give up */
            if (err) {
                LOGW("stdio converter got read error; shutting it down\n");
                break;
            }
        }
    }

    close(pipeStorage->stdoutPipe[0]);
    close(pipeStorage->stderrPipe[0]);

    free(pipeStorage);
    free(stdoutData);
    free(stderrData);

    /* change back for shutdown sequence */
    dvmChangeStatus(NULL, THREAD_RUNNING);
    return NULL;
}

/*
 * Data is pending on "fd".  Read as much as will fit in "data", then
 * write out any full lines and compact "data".
 */
static bool readAndLog(int fd, BufferedData* data, const char* tag)
{
    ssize_t actual;
    size_t want;

    assert(data->count < kMaxLine);

    want = kMaxLine - data->count;
    actual = read(fd, data->buf + data->count, want);
    if (actual <= 0) {
        LOGW("read %s: (%d,%d) failed (%d): %s\n",
            tag, fd, want, (int)actual, strerror(errno));
        return false;
    } else {
        //LOGI("read %s: %d at %d\n", tag, actual, data->count);
    }
    data->count += actual;

    /*
     * Got more data, look for an EOL.  We expect LF or CRLF, but will
     * try to handle a standalone CR.
     */
    char* cp = data->buf;
    const char* start = data->buf;
    int i = data->count;
    for (i = data->count; i > 0; i--, cp++) {
        if (*cp == '\n' || (*cp == '\r' && i != 0 && *(cp+1) != '\n')) {
            *cp = '\0';
            //LOGW("GOT %d at %d '%s'\n", cp - start, start - data->buf, start);
            LOG(LOG_INFO, tag, "%s", start);
            start = cp+1;
        }
    }

    /*
     * See if we overflowed.  If so, cut it off.
     */
    if (start == data->buf && data->count == kMaxLine) {
        data->buf[kMaxLine] = '\0';
        LOG(LOG_INFO, tag, "%s!", start);
        start = cp + kMaxLine;
    }

    /*
     * Update "data" if we consumed some output.  If there's anything left
     * in the buffer, it's because we didn't see an EOL and need to keep
     * reading until we see one.
     */
    if (start != data->buf) {
        if (start >= data->buf + data->count) {
            /* consumed all available */
            data->count = 0;
        } else {
            /* some left over */
            int remaining = data->count - (start - data->buf);
            memmove(data->buf, start, remaining);
            data->count = remaining;
        }
    }

    return true;
}
