/*
 * Copyright (C) 2013 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.
 */

#define LOG_TAG "ProcessCallStack"
// #define LOG_NDEBUG 0

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/ProcessCallStack.h>
#include <utils/Printer.h>

#include <limits.h>

namespace android {

enum {
    // Max sizes for various dynamically generated strings
    MAX_TIME_STRING = 64,
    MAX_PROC_PATH = 1024,

    // Dump related prettiness constants
    IGNORE_DEPTH_CURRENT_THREAD = 2,
};

static const char* CALL_STACK_PREFIX = "  ";
static const char* PATH_THREAD_NAME = "/proc/self/task/%d/comm";
static const char* PATH_SELF_TASK = "/proc/self/task";

static void dumpProcessHeader(Printer& printer, pid_t pid, const char* timeStr) {
    if (timeStr == NULL) {
        ALOGW("%s: timeStr was NULL", __FUNCTION__);
        return;
    }

    char path[PATH_MAX];
    char procNameBuf[MAX_PROC_PATH];
    char* procName = NULL;
    FILE* fp;

    snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
    if ((fp = fopen(path, "r"))) {
        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);
        fclose(fp);
    }

    if (!procName) {
        procName = const_cast<char*>("<unknown>");
    }

    printer.printLine();
    printer.printLine();
    printer.printFormatLine("----- pid %d at %s -----", pid, timeStr);
    printer.printFormatLine("Cmd line: %s", procName);
}

static void dumpProcessFooter(Printer& printer, pid_t pid) {
    printer.printLine();
    printer.printFormatLine("----- end %d -----", pid);
    printer.printLine();
}

static String8 getThreadName(pid_t tid) {
    char path[PATH_MAX];
    char* procName = NULL;
    char procNameBuf[MAX_PROC_PATH];
    FILE* fp;

    snprintf(path, sizeof(path), PATH_THREAD_NAME, tid);
    if ((fp = fopen(path, "r"))) {
        procName = fgets(procNameBuf, sizeof(procNameBuf), fp);
        fclose(fp);
    } else {
        ALOGE("%s: Failed to open %s", __FUNCTION__, path);
    }

    if (procName == NULL) {
        // Reading /proc/self/task/%d/comm failed due to a race
        return String8::format("[err-unknown-tid-%d]", tid);
    }

    // Strip ending newline
    strtok(procName, "\n");

    return String8(procName);
}

static String8 getTimeString(struct tm tm) {
    char timestr[MAX_TIME_STRING];
    // i.e. '2013-10-22 14:42:05'
    strftime(timestr, sizeof(timestr), "%F %T", &tm);

    return String8(timestr);
}

/*
 * Implementation of ProcessCallStack
 */
ProcessCallStack::ProcessCallStack() {
}

ProcessCallStack::ProcessCallStack(const ProcessCallStack& rhs) :
        mThreadMap(rhs.mThreadMap),
        mTimeUpdated(rhs.mTimeUpdated) {
}

ProcessCallStack::~ProcessCallStack() {
}

void ProcessCallStack::clear() {
    mThreadMap.clear();
    mTimeUpdated = tm();
}

void ProcessCallStack::update() {
    DIR *dp;
    struct dirent *ep;
    struct dirent entry;

    dp = opendir(PATH_SELF_TASK);
    if (dp == NULL) {
        ALOGE("%s: Failed to update the process's call stacks: %s",
              __FUNCTION__, strerror(errno));
        return;
    }

    pid_t selfPid = getpid();

    clear();

    // Get current time.
#ifndef USE_MINGW
    {
        time_t t = time(NULL);
        struct tm tm;
        localtime_r(&t, &tm);

        mTimeUpdated = tm;
    }

    /*
     * Each tid is a directory inside of /proc/self/task
     * - Read every file in directory => get every tid
     */
    int code;
    while ((code = readdir_r(dp, &entry, &ep)) == 0 && ep != NULL) {
        pid_t tid = -1;
        sscanf(ep->d_name, "%d", &tid);

        if (tid < 0) {
            // Ignore '.' and '..'
            ALOGV("%s: Failed to read tid from %s/%s",
                  __FUNCTION__, PATH_SELF_TASK, ep->d_name);
            continue;
        }

        ssize_t idx = mThreadMap.add(tid, ThreadInfo());
        if (idx < 0) { // returns negative error value on error
            ALOGE("%s: Failed to add new ThreadInfo: %s",
                  __FUNCTION__, strerror(-idx));
            continue;
        }

        ThreadInfo& threadInfo = mThreadMap.editValueAt(static_cast<size_t>(idx));

        /*
         * Ignore CallStack::update and ProcessCallStack::update for current thread
         * - Every other thread doesn't need this since we call update off-thread
         */
        int ignoreDepth = (selfPid == tid) ? IGNORE_DEPTH_CURRENT_THREAD : 0;

        // Update thread's call stacks
        threadInfo.callStack.update(ignoreDepth, tid);

        // Read/save thread name
        threadInfo.threadName = getThreadName(tid);

        ALOGV("%s: Got call stack for tid %d (size %zu)",
              __FUNCTION__, tid, threadInfo.callStack.size());
    }
    if (code != 0) { // returns positive error value on error
        ALOGE("%s: Failed to readdir from %s: %s",
              __FUNCTION__, PATH_SELF_TASK, strerror(code));
    }
#endif

    closedir(dp);
}

void ProcessCallStack::log(const char* logtag, android_LogPriority priority,
                           const char* prefix) const {
    LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);
    print(printer);
}

void ProcessCallStack::print(Printer& printer) const {
    /*
     * Print the header/footer with the regular printer.
     * Print the callstack with an additional two spaces as the prefix for legibility.
     */
    PrefixPrinter csPrinter(printer, CALL_STACK_PREFIX);
    printInternal(printer, csPrinter);
}

void ProcessCallStack::printInternal(Printer& printer, Printer& csPrinter) const {
    dumpProcessHeader(printer, getpid(),
                      getTimeString(mTimeUpdated).string());

    for (size_t i = 0; i < mThreadMap.size(); ++i) {
        pid_t tid = mThreadMap.keyAt(i);
        const ThreadInfo& threadInfo = mThreadMap.valueAt(i);
        const String8& threadName = threadInfo.threadName;

        printer.printLine("");
        printer.printFormatLine("\"%s\" sysTid=%d", threadName.string(), tid);

        threadInfo.callStack.print(csPrinter);
    }

    dumpProcessFooter(printer, getpid());
}

void ProcessCallStack::dump(int fd, int indent, const char* prefix) const {

    if (indent < 0) {
        ALOGW("%s: Bad indent (%d)", __FUNCTION__, indent);
        return;
    }

    FdPrinter printer(fd, static_cast<unsigned int>(indent), prefix);
    print(printer);
}

String8 ProcessCallStack::toString(const char* prefix) const {

    String8 dest;
    String8Printer printer(&dest, prefix);
    print(printer);

    return dest;
}

size_t ProcessCallStack::size() const {
    return mThreadMap.size();
}

}; //namespace android
