/*
 * Copyright (C) 2018 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 <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <fstream>
#include <iterator>
#if defined(__ANDROID__) && !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
#include "bpf/BpfMap.h"
#endif
#include <sstream>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <dmabufinfo/dmabuf_sysfs_stats.h>

#include "meminfo_private.h"

namespace android {
namespace meminfo {

bool SysMemInfo::ReadMemInfo(const char* path) {
    return ReadMemInfo(path, SysMemInfo::kDefaultSysMemInfoTags.size(),
                       &*SysMemInfo::kDefaultSysMemInfoTags.begin(),
                       [&](std::string_view tag, uint64_t val) {
                           // Safe to store the string_view in the map
                           // because the tags from
                           // kDefaultSysMemInfoTags are all
                           // statically-allocated.
                           mem_in_kb_[tag] = val;
                       });
}

bool SysMemInfo::ReadMemInfo(std::vector<uint64_t>* out, const char* path) {
    out->clear();
    out->resize(SysMemInfo::kDefaultSysMemInfoTags.size());
    return ReadMemInfo(SysMemInfo::kDefaultSysMemInfoTags.size(),
                       &*SysMemInfo::kDefaultSysMemInfoTags.begin(), out->data(), path);
}

bool SysMemInfo::ReadMemInfo(size_t ntags, const std::string_view* tags, uint64_t* out,
                             const char* path) {
    return ReadMemInfo(path, ntags, tags, [&]([[maybe_unused]] std::string_view tag, uint64_t val) {
        auto it = std::find(tags, tags + ntags, tag);
        if (it == tags + ntags) {
            LOG(ERROR) << "Tried to store invalid tag: " << tag;
            return;
        }
        auto index = std::distance(tags, it);
        // store the values in the same order as the tags
        out[index] = val;
    });
}

uint64_t SysMemInfo::ReadVmallocInfo() {
    return ::android::meminfo::ReadVmallocInfo();
}

bool SysMemInfo::ReadMemInfo(const char* path, size_t ntags, const std::string_view* tags,
                             std::function<void(std::string_view, uint64_t)> store_val) {
    char buffer[4096];
    int fd = open(path, O_RDONLY | O_CLOEXEC);
    if (fd < 0) {
        PLOG(ERROR) << "Failed to open file :" << path;
        return false;
    }

    const int len = read(fd, buffer, sizeof(buffer) - 1);
    close(fd);
    if (len < 0) {
        return false;
    }

    buffer[len] = '\0';
    char* p = buffer;
    uint32_t found = 0;
    uint32_t lineno = 0;
    bool zram_tag_found = false;
    while (*p && found < ntags) {
        for (size_t tagno = 0; tagno < ntags; ++tagno) {
            const std::string_view& tag = tags[tagno];
            // Special case for "Zram:" tag that android_os_Debug and friends look
            // up along with the rest of the numbers from /proc/meminfo
            if (!zram_tag_found && tag == "Zram:") {
                store_val(tag, mem_zram_kb());
                zram_tag_found = true;
                found++;
                continue;
            }

            if (strncmp(p, tag.data(), tag.size()) == 0) {
                p += tag.size();
                while (*p == ' ') p++;
                char* endptr = nullptr;
                uint64_t val = strtoull(p, &endptr, 10);
                if (p == endptr) {
                    PLOG(ERROR) << "Failed to parse line:" << lineno + 1 << " in file: " << path;
                    return false;
                }
                store_val(tag, val);
                p = endptr;
                found++;
                break;
            }
        }

        while (*p && *p != '\n') {
            p++;
        }
        if (*p) p++;
        lineno++;
    }

    return true;
}

uint64_t SysMemInfo::mem_zram_kb(const char* zram_dev_cstr) {
    uint64_t mem_zram_total = 0;
    if (zram_dev_cstr) {
        if (!MemZramDevice(zram_dev_cstr, &mem_zram_total)) {
            return 0;
        }
        return mem_zram_total / 1024;
    }

    constexpr uint32_t kMaxZramDevices = 256;
    for (uint32_t i = 0; i < kMaxZramDevices; i++) {
        std::string zram_dev_abspath = ::android::base::StringPrintf("/sys/block/zram%u/", i);
        if (access(zram_dev_abspath.c_str(), F_OK)) {
            // We assume zram devices appear in range 0-255 and appear always in sequence
            // under /sys/block. So, stop looking for them once we find one is missing.
            break;
        }

        uint64_t mem_zram_dev;
        if (!MemZramDevice(zram_dev_abspath.c_str(), &mem_zram_dev)) {
            return 0;
        }

        mem_zram_total += mem_zram_dev;
    }

    return mem_zram_total / 1024;
}

bool SysMemInfo::MemZramDevice(const char* zram_dev, uint64_t* mem_zram_dev) {
    std::string mmstat = ::android::base::StringPrintf("%s/%s", zram_dev, "mm_stat");
    auto mmstat_fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(mmstat.c_str(), "re"), fclose};
    if (mmstat_fp != nullptr) {
        // only if we do have mmstat, use it. Otherwise, fall through to trying out the old
        // 'mem_used_total'
        if (fscanf(mmstat_fp.get(), "%*" SCNu64 " %*" SCNu64 " %" SCNu64, mem_zram_dev) != 1) {
            PLOG(ERROR) << "Malformed mm_stat file in: " << zram_dev;
            return false;
        }
        return true;
    }

    std::string content;
    if (::android::base::ReadFileToString(
                ::android::base::StringPrintf("%s/mem_used_total", zram_dev), &content)) {
        *mem_zram_dev = strtoull(content.c_str(), NULL, 10);
        if (*mem_zram_dev == ULLONG_MAX) {
            PLOG(ERROR) << "Malformed mem_used_total file for zram dev: " << zram_dev
                        << " content: " << content;
            return false;
        }

        return true;
    }

    LOG(ERROR) << "Can't find memory status under: " << zram_dev;
    return false;
}

// Public methods
uint64_t ReadVmallocInfo(const char* path) {
    uint64_t vmalloc_total = 0;
    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path, "re"), fclose};
    if (fp == nullptr) {
        return vmalloc_total;
    }

    char* line = nullptr;
    size_t line_alloc = 0;
    while (getline(&line, &line_alloc, fp.get()) > 0) {
        // We are looking for lines like
        //
        // 0x0000000000000000-0x0000000000000000   12288 drm_property_create_blob+0x44/0xec pages=2 vmalloc
        // 0x0000000000000000-0x0000000000000000    8192 wlan_logging_sock_init_svc+0xf8/0x4f0 [wlan] pages=1 vmalloc
        //
        // Notice that if the caller is coming from a module, the kernel prints and extra
        // "[module_name]" after the address and the symbol of the call site. This means we can't
        // use the old sscanf() method of getting the # of pages.
        char* p_start = strstr(line, "pages=");
        if (p_start == nullptr) {
            // we didn't find anything
            continue;
        }

        uint64_t nr_pages;
        if (sscanf(p_start, "pages=%" SCNu64 "", &nr_pages) == 1) {
            vmalloc_total += (nr_pages * getpagesize());
        }
    }

    free(line);

    return vmalloc_total;
}

static bool ReadSysfsFile(const std::string& path, uint64_t* value) {
    std::string content;
    if (!::android::base::ReadFileToString(path, &content)) {
        LOG(ERROR) << "Can't open file: " << path;
        return false;
    }

    *value = strtoull(content.c_str(), NULL, 10);
    if (*value == ULLONG_MAX) {
        PLOG(ERROR) << "Invalid file format: " << path;
        return false;
    }

    return true;
}

bool ReadIonHeapsSizeKb(uint64_t* size, const std::string& path) {
    return ReadSysfsFile(path, size);
}

bool ReadIonPoolsSizeKb(uint64_t* size, const std::string& path) {
    return ReadSysfsFile(path, size);
}

bool ReadDmabufHeapPoolsSizeKb(uint64_t* size, const std::string& dma_heap_pool_size_path) {
    static bool support_dmabuf_heap_pool_size = [dma_heap_pool_size_path]() -> bool {
        bool ret = (access(dma_heap_pool_size_path.c_str(), R_OK) == 0);
        if (!ret)
            LOG(ERROR) << "Unable to read DMA-BUF heap total pool size, read ION total pool "
                          "size instead.";
        return ret;
    }();

    if (!support_dmabuf_heap_pool_size) return ReadIonPoolsSizeKb(size);

    return ReadSysfsFile(dma_heap_pool_size_path, size);
}

bool ReadDmabufHeapTotalExportedKb(uint64_t* size, const std::string& dma_heap_root_path,
                                   const std::string& dmabuf_sysfs_stats_path) {
    static bool support_dmabuf_heaps = [dma_heap_root_path]() -> bool {
        bool ret = (access(dma_heap_root_path.c_str(), R_OK) == 0);
        if (!ret) LOG(ERROR) << "DMA-BUF heaps not supported, read ION heap total instead.";
        return ret;
    }();

    if (!support_dmabuf_heaps) return ReadIonHeapsSizeKb(size);

    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(dma_heap_root_path.c_str()), closedir);

    if (!dir) {
        return false;
    }

    std::unordered_set<std::string> heap_list;
    struct dirent* dent;
    while ((dent = readdir(dir.get()))) {
        if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue;

        heap_list.insert(dent->d_name);
    }

    if (heap_list.empty()) return false;

    android::dmabufinfo::DmabufSysfsStats stats;
    if (!android::dmabufinfo::GetDmabufSysfsStats(&stats, dmabuf_sysfs_stats_path)) return false;

    auto exporter_info = stats.exporter_info();

    *size = 0;
    for (const auto& heap : heap_list) {
        auto iter = exporter_info.find(heap);
        if (iter != exporter_info.end()) *size += iter->second.size;
    }

    *size = *size / 1024;

    return true;
}

bool ReadPerProcessGpuMem([[maybe_unused]] std::unordered_map<uint32_t, uint64_t>* out) {
#if defined(__ANDROID__) && !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
    static constexpr const char kBpfGpuMemTotalMap[] = "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";

    // Use the read-only wrapper BpfMapRO to properly retrieve the read-only map.
    auto map = bpf::BpfMapRO<uint64_t, uint64_t>(kBpfGpuMemTotalMap);
    if (!map.isValid()) {
        LOG(ERROR) << "Can't open file: " << kBpfGpuMemTotalMap;
        return false;
    }

    if (!out) {
        LOG(ERROR) << "ReadPerProcessGpuMem: out param is null";
        return false;
    }
    out->clear();

    auto map_key = map.getFirstKey();
    if (!map_key.ok()) {
        return true;
    }

    do {
        uint64_t key = map_key.value();
        uint32_t pid = key;  // BPF Key [32-bits GPU ID | 32-bits PID]

        auto gpu_mem = map.readValue(key);
        if (!gpu_mem.ok()) {
            LOG(ERROR) << "Invalid file format: " << kBpfGpuMemTotalMap;
            return false;
        }

        const auto& iter = out->find(pid);
        if (iter == out->end()) {
            out->insert({pid, gpu_mem.value() / 1024});
        } else {
            iter->second += gpu_mem.value() / 1024;
        }

        map_key = map.getNextKey(key);
    } while (map_key.ok());

    return true;
#else
    return false;
#endif
}

bool ReadProcessGpuUsageKb([[maybe_unused]] uint32_t pid, [[maybe_unused]] uint32_t gpu_id,
                           uint64_t* size) {
#if defined(__ANDROID__) && !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
    static constexpr const char kBpfGpuMemTotalMap[] = "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";

    uint64_t gpu_mem;

    // BPF Key [32-bits GPU ID | 32-bits PID]
    uint64_t kBpfKeyGpuUsage = ((uint64_t)gpu_id << 32) | pid;

    // Use the read-only wrapper BpfMapRO to properly retrieve the read-only map.
    auto map = bpf::BpfMapRO<uint64_t, uint64_t>(kBpfGpuMemTotalMap);
    if (!map.isValid()) {
        LOG(ERROR) << "Can't open file: " << kBpfGpuMemTotalMap;
        return false;
    }

    auto res = map.readValue(kBpfKeyGpuUsage);

    if (res.ok()) {
        gpu_mem = res.value();
    } else if (res.error().code() == ENOENT) {
        gpu_mem = 0;
    } else {
        LOG(ERROR) << "Invalid file format: " << kBpfGpuMemTotalMap;
        return false;
    }

    if (size) {
        *size = gpu_mem / 1024;
    }
    return true;
#else
    if (size) {
        *size = 0;
    }
    return false;
#endif
}

bool ReadGpuTotalUsageKb(uint64_t* size) {
    // gpu_mem_total tracepoint defines PID 0 as global total
    // GPU ID 0 suffices for current android devices.
    // This will need to check all GPU IDs in future if more than
    // one is GPU device is present on the device.
    return ReadProcessGpuUsageKb(0, 0, size);
}

}  // namespace meminfo
}  // namespace android
