/*
 * Copyright (C) 2019 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 <getopt.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <meminfo/procmeminfo.h>

using ::android::meminfo::Vma;

struct VmaInfo {
    Vma vma;
    bool is_bss;
    uint32_t count;

    VmaInfo() = default;
    VmaInfo(const Vma& v) : vma(v), is_bss(false), count(1) {}
    VmaInfo(const Vma& v, bool bss) : vma(v), is_bss(bss), count(1) {}
    VmaInfo(const Vma& v, const std::string& name, bool bss) : vma(v), is_bss(bss), count(1) {
        vma.name = name;
    }
};

// Global options
static std::string g_filename = "";
static bool g_merge_by_names = false;
static bool g_terse = false;
static bool g_verbose = false;
static bool g_show_addr = false;
static bool g_quiet = false;
static pid_t g_pid = -1;

static VmaInfo g_total;
static std::vector<VmaInfo> g_vmas;

[[noreturn]] static void usage(int exit_status) {
    fprintf(stderr,
            "%s [-aqtv] [-f FILE] PID\n"
            "-a\taddresses (show virtual memory map)\n"
            "-q\tquiet (don't show error if map could not be read)\n"
            "-t\tterse (show only items with private pages)\n"
            "-v\tverbose (don't coalesce maps with the same name)\n"
            "-f\tFILE (read from input from FILE instead of PID)\n",
            getprogname());

    exit(exit_status);
}

static bool is_library(const std::string& name) {
    return (name.size() > 4) && (name[0] == '/') && ::android::base::EndsWith(name, ".so");
}

static bool insert_before(const VmaInfo& a, const VmaInfo& b) {
    if (g_show_addr) {
        return (a.vma.start < b.vma.start || (a.vma.start == b.vma.start && a.vma.end < b.vma.end));
    }

    return strcmp(a.vma.name.c_str(), b.vma.name.c_str()) < 0;
}

static void collect_vma(const Vma& vma) {
    if (g_vmas.empty()) {
        g_vmas.emplace_back(vma);
        return;
    }

    VmaInfo current(vma);
    VmaInfo& last = g_vmas.back();
    // determine if this is bss;
    if (vma.name.empty()) {
        if (last.vma.end == current.vma.start && is_library(last.vma.name)) {
            current.vma.name = last.vma.name;
            current.is_bss = true;
        } else {
            current.vma.name = "[anon]";
        }
    }

    std::vector<VmaInfo>::iterator it;
    for (it = g_vmas.begin(); it != g_vmas.end(); it++) {
        if (g_merge_by_names && (it->vma.name == current.vma.name)) {
            it->vma.usage.vss += current.vma.usage.vss;
            it->vma.usage.rss += current.vma.usage.rss;
            it->vma.usage.pss += current.vma.usage.pss;

            it->vma.usage.shared_clean += current.vma.usage.shared_clean;
            it->vma.usage.shared_dirty += current.vma.usage.shared_dirty;
            it->vma.usage.private_clean += current.vma.usage.private_clean;
            it->vma.usage.private_dirty += current.vma.usage.private_dirty;
            it->vma.usage.swap += current.vma.usage.swap;
            it->vma.usage.swap_pss += current.vma.usage.swap_pss;
            it->is_bss &= current.is_bss;
            it->count++;
            break;
        }

        if (insert_before(current, *it)) {
            g_vmas.insert(it, current);
            break;
        }
    }

    if (it == g_vmas.end()) {
        g_vmas.emplace_back(current);
    }
}

static void print_header() {
    const char* addr1 = g_show_addr ? "           start              end " : "";
    const char* addr2 = g_show_addr ? "            addr             addr " : "";

    printf("%s virtual                     shared   shared  private  private\n", addr1);
    printf("%s    size      RSS      PSS    clean    dirty    clean    dirty     swap  swapPSS",
           addr2);
    if (!g_verbose && !g_show_addr) {
        printf("   # ");
    }
    printf(" object\n");
}

static void print_divider() {
    if (g_show_addr) {
        printf("-------- -------- ");
    }
    printf("-------- -------- -------- -------- -------- -------- -------- -------- -------- ");
    if (!g_verbose && !g_show_addr) {
        printf("---- ");
    }
    printf("------------------------------\n");
}

static void print_vmainfo(const VmaInfo& v, bool total) {
    if (g_show_addr) {
        if (total) {
            printf("                                  ");
        } else {
            printf("%16" PRIx64 " %16" PRIx64 " ", v.vma.start, v.vma.end);
        }
    }
    printf("%8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64
           " %8" PRIu64 " %8" PRIu64 " ",
           v.vma.usage.vss, v.vma.usage.rss, v.vma.usage.pss, v.vma.usage.shared_clean,
           v.vma.usage.shared_dirty, v.vma.usage.private_clean, v.vma.usage.private_dirty,
           v.vma.usage.swap, v.vma.usage.swap_pss);
    if (!g_verbose && !g_show_addr) {
        printf("%4" PRIu32 " ", v.count);
    }
}

static int showmap(void) {
    if (!::android::meminfo::ForEachVmaFromFile(g_filename, collect_vma)) {
        if (!g_quiet) {
            fprintf(stderr, "Failed to parse file %s\n", g_filename.c_str());
        }
        return 1;
    }

    print_header();
    print_divider();

    for (const auto& v : g_vmas) {
        g_total.vma.usage.vss += v.vma.usage.vss;
        g_total.vma.usage.rss += v.vma.usage.rss;
        g_total.vma.usage.pss += v.vma.usage.pss;

        g_total.vma.usage.private_clean += v.vma.usage.private_clean;
        g_total.vma.usage.private_dirty += v.vma.usage.private_dirty;
        g_total.vma.usage.shared_clean += v.vma.usage.shared_clean;
        g_total.vma.usage.shared_dirty += v.vma.usage.shared_dirty;

        g_total.vma.usage.swap += v.vma.usage.swap;
        g_total.vma.usage.swap_pss += v.vma.usage.swap_pss;
        g_total.count += v.count;

        if (g_terse && !(v.vma.usage.private_dirty || v.vma.usage.private_clean)) {
            continue;
        }

        print_vmainfo(v, false);
        printf("%s%s\n", v.vma.name.c_str(), v.is_bss ? " [bss]" : "");
    }

    print_divider();
    print_header();
    print_divider();

    print_vmainfo(g_total, true);
    printf("TOTAL\n");

    return 0;
}

int main(int argc, char* argv[]) {
    signal(SIGPIPE, SIG_IGN);
    struct option longopts[] = {
            {"help", no_argument, nullptr, 'h'},
            {0, 0, nullptr, 0},
    };

    int opt;
    while ((opt = getopt_long(argc, argv, "tvaqf:h", longopts, nullptr)) != -1) {
        switch (opt) {
            case 't':
                g_terse = true;
                break;
            case 'a':
                g_show_addr = true;
                break;
            case 'v':
                g_verbose = true;
                break;
            case 'q':
                g_quiet = true;
                break;
            case 'f':
                g_filename = optarg;
                break;
            case 'h':
                usage(EXIT_SUCCESS);
            default:
                usage(EXIT_FAILURE);
        }
    }

    if (g_filename.empty()) {
        if ((argc - 1) < optind) {
            fprintf(stderr, "Invalid arguments: Must provide <pid> at the end\n");
            usage(EXIT_FAILURE);
        }

        g_pid = atoi(argv[optind]);
        if (g_pid <= 0) {
            fprintf(stderr, "Invalid process id %s\n", argv[optind]);
            usage(EXIT_FAILURE);
        }

        g_filename = ::android::base::StringPrintf("/proc/%d/smaps", g_pid);
    }

    g_merge_by_names = !g_verbose && !g_show_addr;
    return showmap();
}
