/*
 * 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 <string.h>
#include <stdio.h>
#include <dirent.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);
    }

    // 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(int32_t maxDepth) {
    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 (errno = %d, '%s')",
              __FUNCTION__, errno, 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 (errno = %zd, '%s')",
                  __FUNCTION__, idx, 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
        CallStack& cs = threadInfo.callStack;
        cs.update(ignoreDepth, maxDepth, tid);

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

        ALOGV("%s: Got call stack for tid %d (size %zu)",
              __FUNCTION__, tid, cs.size());
    }
    if (code != 0) { // returns positive error value on error
        ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')",
              __FUNCTION__, PATH_SELF_TASK, -code, 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 CallStack& cs = threadInfo.callStack;
        const String8& threadName = threadInfo.threadName;

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

        cs.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
