/*
 * 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 <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

// This program is as dumb as possible -- it reads a whole bunch of data
// from /proc and reports when it changes.  It's up to analysis tools to
// actually parse the data.  This program only does enough parsing to split
// large files (/proc/stat, /proc/yaffs) into individual values.
//
// The output format is a repeating series of observed differences:
//
//   T + <beforetime.stamp>
//   /proc/<new_filename> + <contents of newly discovered file>
//   /proc/<changed_filename> = <contents of changed file>
//   /proc/<deleted_filename> -
//   /proc/<filename>:<label> = <part of a multiline file>
//   T - <aftertime.stamp>
//
//
// Files read:
//
// /proc/*/stat       - for all running/selected processes
// /proc/*/wchan      - for all running/selected processes
// /proc/binder/stats - per line: "/proc/binder/stats:BC_REPLY"
// /proc/diskstats    - per device: "/proc/diskstats:mmcblk0"
// /proc/net/dev      - per interface: "/proc/net/dev:rmnet0"
// /proc/stat         - per line: "/proc/stat:intr"
// /proc/yaffs        - per device/line: "/proc/yaffs:userdata:nBlockErasures"
// /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
//                    - per line: "/sys/.../time_in_state:245000"

struct data {
    char *name;            // filename, plus ":var" for many-valued files
    char *value;           // text to be reported when it changes
};

// Like memcpy, but replaces spaces and unprintables with '_'.
static void unspace(char *dest, const char *src, int len) {
    while (len-- > 0) {
        char ch = *src++;
        *dest++ = isgraph(ch) ? ch : '_';
    }
}

// Set data->name and data->value to malloc'd strings with the
// filename and contents of the file.  Trims trailing whitespace.
static void read_data(struct data *data, const char *filename) {
    char buf[4096];
    data->name = strdup(filename);
    int fd = open(filename, O_RDONLY);
    if (fd < 0) {
        data->value = NULL;
        return;
    }

    int len = read(fd, buf, sizeof(buf));
    if (len < 0) {
        perror(filename);
        close(fd);
        data->value = NULL;
        return;
    }

    close(fd);
    while (len > 0 && isspace(buf[len - 1])) --len;
    data->value = malloc(len + 1);
    memcpy(data->value, buf, len);
    data->value[len] = '\0';
}

// Read a name/value file and write data entries for each line.
// Returns the number of entries written (always <= stats_count).
//
// delimiter: used to split each line into name and value
// terminator: if non-NULL, processing stops after this string
// skip_words: skip this many words at the start of each line
static int read_lines(
        const char *filename,
        char delimiter, const char *terminator, int skip_words,
        struct data *stats, int stats_count) {
    char buf[8192];
    int fd = open(filename, O_RDONLY);
    if (fd < 0) return 0;

    int len = read(fd, buf, sizeof(buf) - 1);
    if (len < 0) {
        perror(filename);
        close(fd);
        return 0;
    }
    buf[len] = '\0';
    close(fd);

    if (terminator != NULL) {
        char *end = strstr(buf, terminator);
        if (end != NULL) *end = '\0';
    }

    int filename_len = strlen(filename);
    int num = 0;
    char *line;
    for (line = strtok(buf, "\n");
         line != NULL && num < stats_count;
         line = strtok(NULL, "\n")) {
        // Line format: <sp>name<delim><sp>value

        int i;
        while (isspace(*line)) ++line;
        for (i = 0; i < skip_words; ++i) {
            while (isgraph(*line)) ++line;
            while (isspace(*line)) ++line;
        }

        char *name_end = strchr(line, delimiter);
        if (name_end == NULL) continue;

        // Key format: <filename>:<name>
        struct data *data = &stats[num++];
        data->name = malloc(filename_len + 1 + (name_end - line) + 1);
        unspace(data->name, filename, filename_len);
        data->name[filename_len] = ':';
        unspace(data->name + filename_len + 1, line, name_end - line);
        data->name[filename_len + 1 + (name_end - line)] = '\0';

        char *value = name_end + 1;
        while (isspace(*value)) ++value;
        data->value = strdup(value);
    }

    return num;
}

// Read /proc/yaffs and write data entries for each line.
// Returns the number of entries written (always <= stats_count).
static int read_proc_yaffs(struct data *stats, int stats_count) {
    char buf[8192];
    int fd = open("/proc/yaffs", O_RDONLY);
    if (fd < 0) return 0;

    int len = read(fd, buf, sizeof(buf) - 1);
    if (len < 0) {
        perror("/proc/yaffs");
        close(fd);
        return 0;
    }
    buf[len] = '\0';
    close(fd);

    int num = 0, device_len = 0;
    char *line, *device = NULL;
    for (line = strtok(buf, "\n");
         line != NULL && num < stats_count;
         line = strtok(NULL, "\n")) {
        if (strncmp(line, "Device ", 7) == 0) {
            device = strchr(line, '"');
            if (device != NULL) {
                char *end = strchr(++device, '"');
                if (end != NULL) *end = '\0';
                device_len = strlen(device);
            }
            continue;
        }
        if (device == NULL) continue;

        char *name_end = line + strcspn(line, " .");
        if (name_end == line || *name_end == '\0') continue;

        struct data *data = &stats[num++];
        data->name = malloc(12 + device_len + 1 + (name_end - line) + 1);
        memcpy(data->name, "/proc/yaffs:", 12);
        unspace(data->name + 12, device, device_len);
        data->name[12 + device_len] = ':';
        unspace(data->name + 12 + device_len + 1, line, name_end - line);
        data->name[12 + device_len + 1 + (name_end - line)] = '\0';

        char *value = name_end;
        while (*value == '.' || isspace(*value)) ++value;
        data->value = strdup(value);
    }

    return num;
}

// Compare two "struct data" records by their name.
static int compare_data(const void *a, const void *b) {
    const struct data *data_a = (const struct data *) a;
    const struct data *data_b = (const struct data *) b;
    return strcmp(data_a->name, data_b->name);
}

// Return a malloc'd array of "struct data" read from all over /proc.
// The array is sorted by name and terminated by a record with name == NULL.
static struct data *read_stats(char *names[], int name_count) {
    static int bad[4096];  // Cache pids known not to match patterns
    static size_t bad_count = 0;

    int pids[4096];
    size_t pid_count = 0;

    DIR *proc_dir = opendir("/proc");
    if (proc_dir == NULL) {
        perror("Can't scan /proc");
        exit(1);
    }

    size_t bad_pos = 0;
    char filename[1024];
    struct dirent *proc_entry;
    while ((proc_entry = readdir(proc_dir))) {
        int pid = atoi(proc_entry->d_name);
        if (pid <= 0) continue;

        if (name_count > 0) {
            while (bad_pos < bad_count && bad[bad_pos] < pid) ++bad_pos;
            if (bad_pos < bad_count && bad[bad_pos] == pid) continue;

            char cmdline[4096];
            sprintf(filename, "/proc/%d/cmdline", pid);
            int fd = open(filename, O_RDONLY);
            if (fd < 0) {
                perror(filename);
                continue;
            }

            int len = read(fd, cmdline, sizeof(cmdline) - 1);
            if (len < 0) {
                perror(filename);
                close(fd);
                continue;
            }

            close(fd);
            cmdline[len] = '\0';
            int n;
            for (n = 0; n < name_count && !strstr(cmdline, names[n]); ++n);

            if (n == name_count) {
                // Insertion sort -- pids mostly increase so this makes sense
                if (bad_count < sizeof(bad) / sizeof(bad[0])) {
                    int pos = bad_count++;
                    while (pos > 0 && bad[pos - 1] > pid) {
                        bad[pos] = bad[pos - 1];
                        --pos;
                    }
                    bad[pos] = pid;
                }
                continue;
            }
        }

        if (pid_count >= sizeof(pids) / sizeof(pids[0])) {
            fprintf(stderr, "warning: >%zu processes\n", pid_count);
        } else {
            pids[pid_count++] = pid;
        }
    }
    closedir(proc_dir);

    size_t i, stats_count = pid_count * 2 + 200;  // 200 for stat, yaffs, etc.
    struct data *stats = malloc((stats_count + 1) * sizeof(struct data));
    struct data *next = stats;
    for (i = 0; i < pid_count; i++) {
        assert(pids[i] > 0);
        sprintf(filename, "/proc/%d/stat", pids[i]);
        read_data(next++, filename);
        sprintf(filename, "/proc/%d/wchan", pids[i]);
        read_data(next++, filename);
    }

    struct data *end = stats + stats_count;
    next += read_proc_yaffs(next, stats + stats_count - next);
    next += read_lines("/proc/net/dev", ':', NULL, 0, next, end - next);
    next += read_lines("/proc/stat", ' ', NULL, 0, next, end - next);
    next += read_lines("/proc/binder/stats", ':', "\nproc ", 0, next, end - next);
    next += read_lines("/proc/diskstats", ' ', NULL, 2, next, end - next);
    next += read_lines(
            "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state",
            ' ', NULL, 0, next, end - next);

    assert(next < stats + stats_count);
    next->name = NULL;
    next->value = NULL;
    qsort(stats, next - stats, sizeof(struct data), compare_data);
    return stats;
}

// Print stats which have changed from one sorted array to the next.
static void diff_stats(struct data *old_stats, struct data *new_stats) {
    while (old_stats->name != NULL || new_stats->name != NULL) {
        int compare;
        if (old_stats->name == NULL) {
            compare = 1;
        } else if (new_stats->name == NULL) {
            compare = -1;
        } else {
            compare = compare_data(old_stats, new_stats);
        }

        if (compare < 0) {
            // old_stats no longer present
            if (old_stats->value != NULL) {
                printf("%s -\n", old_stats->name);
            }
            ++old_stats;
        } else if (compare > 0) {
            // new_stats is new
            if (new_stats->value != NULL) {
                printf("%s + %s\n", new_stats->name, new_stats->value);
            }
            ++new_stats;
        } else {
            // changed
            if (new_stats->value == NULL) {
                if (old_stats->value != NULL) {
                    printf("%s -\n", old_stats->name);
                }
            } else if (old_stats->value == NULL) {
                printf("%s + %s\n", new_stats->name, new_stats->value);
            } else if (strcmp(old_stats->value, new_stats->value)) {
                printf("%s = %s\n", new_stats->name, new_stats->value);
            }
            ++old_stats;
            ++new_stats;
        }
    }
}

// Free a "struct data" array and all the strings within it.
static void free_stats(struct data *stats) {
    int i;
    for (i = 0; stats[i].name != NULL; ++i) {
        free(stats[i].name);
        free(stats[i].value);
    }
    free(stats);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr,
                "usage: procstatlog poll_interval [procname ...] > procstat.log\n\n"
                "\n"
                "Scans process status every poll_interval seconds (e.g. 0.1)\n"
                "and writes data from /proc/stat, /proc/*/stat files, and\n"
                "other /proc status files every time something changes.\n"
                "\n"
                "Scans all processes by default.  Listing some process name\n"
                "substrings will limit scanning and reduce overhead.\n"
                "\n"
                "Data is logged continuously until the program is killed.\n");
        return 2;
    }

    long poll_usec = (long) (atof(argv[1]) * 1000000l);
    if (poll_usec <= 0) {
        fprintf(stderr, "illegal poll interval: %s\n", argv[1]);
        return 2;
    }

    struct data *old_stats = malloc(sizeof(struct data));
    old_stats->name = NULL;
    old_stats->value = NULL;
    while (1) {
        struct timeval before, after;
        gettimeofday(&before, NULL);
        printf("T + %ld.%06ld\n", before.tv_sec, before.tv_usec);

        struct data *new_stats = read_stats(argv + 2, argc - 2);
        diff_stats(old_stats, new_stats);
        free_stats(old_stats);
        old_stats = new_stats;
        gettimeofday(&after, NULL);
        printf("T - %ld.%06ld\n", after.tv_sec, after.tv_usec);

        long elapsed_usec = (long) after.tv_usec - before.tv_usec;
        elapsed_usec += 1000000l * (after.tv_sec - before.tv_sec);
        if (poll_usec > elapsed_usec) usleep(poll_usec - elapsed_usec);
    }

    return 0;
}
