#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <ctype.h>
#include <stddef.h>
#include <sys/mman.h>
#include <sys/stat.h>

// Initial size of the array holding struct file_info
#define INITIAL_NUM_FILES 512

// Max number of file descriptors to use for ntfw
#define MAX_NUM_FD 1

struct file_info {
    char *name;
    size_t file_size;
    size_t num_cached_pages;
};

// Size of pages on this system
static int g_page_size;

// Total number of cached pages found so far
static size_t g_total_cached = 0;

// Total number of files scanned so far
static size_t g_num_files = 0;

// Scanned files and their associated cached page counts
static struct file_info **g_files;

// Current size of files array
size_t g_files_size;

static struct file_info *get_file_info(const char* fpath, size_t file_size) {
    struct file_info *info;
    if (g_num_files >= g_files_size) {
        g_files = realloc(g_files, 2 * g_files_size * sizeof(struct file_info*));
        if (!g_files) {
            fprintf(stderr, "Couldn't allocate space for files array: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        g_files_size = 2 * g_files_size;
    }

    info = calloc(1, sizeof(*info));
    if (!info) {
        fprintf(stderr, "Couldn't allocate space for file struct: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    info->name = malloc(strlen(fpath) + 1);
    if (!info->name) {
        fprintf(stderr, "Couldn't allocate space for file struct: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    strcpy(info->name, fpath);

    info->num_cached_pages = 0;
    info->file_size = file_size;

    g_files[g_num_files++] = info;

    return info;
}

static int store_num_cached(const char* fpath, const struct stat *sb) {
    int fd;
    fd = open (fpath, O_RDONLY);

    if (fd == -1) {
        printf("Could not open file.");
        return -1;
    }

    void* mapped_addr = mmap(NULL, sb->st_size, PROT_NONE, MAP_SHARED, fd, 0);

    if (mapped_addr != MAP_FAILED) {
        // Calculate bit-vector size
        size_t num_file_pages = (sb->st_size + g_page_size - 1) / g_page_size;
        unsigned char* mincore_data = calloc(1, num_file_pages);
        int ret = mincore(mapped_addr, sb->st_size, mincore_data);
        int num_cached = 0;
        unsigned int page = 0;
        for (page = 0; page < num_file_pages; page++) {
           if (mincore_data[page]) num_cached++;
        }
        if (num_cached > 0) {
            struct file_info *info = get_file_info(fpath, sb->st_size);
            info->num_cached_pages += num_cached;
            g_total_cached += num_cached;
        }
        munmap(mapped_addr, sb->st_size);
    }

    close(fd);
    return 0;
}

static int scan_entry(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
    if (typeflag == FTW_F) {
        store_num_cached(fpath, sb);
    }
    return 0;
}

static int cmpsize(size_t a, size_t b) {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

static int cmpfiles(const void *a, const void *b) {
    return cmpsize((*((struct file_info**)a))->num_cached_pages,
            (*((struct file_info**)b))->num_cached_pages);
}

int main()
{
    size_t i;
    g_page_size = getpagesize();

    g_files = malloc(INITIAL_NUM_FILES * sizeof(struct file_info*));
    g_files_size = INITIAL_NUM_FILES;

    // Walk filesystem trees
    nftw("/system/", &scan_entry, MAX_NUM_FD, 0);
    nftw("/vendor/", &scan_entry, MAX_NUM_FD, 0);
    nftw("/data/", &scan_entry, MAX_NUM_FD, 0);

    // Sort entries
    qsort(g_files, g_num_files, sizeof(g_files[0]), &cmpfiles);

    // Dump entries
    for (i = 0; i < g_num_files; i++) {
        struct file_info *info = g_files[i];
        fprintf(stdout, "%s: %zu cached pages (%.2f MB, %zu%% of total file size.)\n", info->name,
                info->num_cached_pages,
                (float) (info->num_cached_pages * g_page_size) / 1024 / 1024,
                (100 * info->num_cached_pages * g_page_size) / info->file_size);
    }

    fprintf(stdout, "TOTAL CACHED: %zu pages (%f MB)\n", g_total_cached,
            (float) (g_total_cached * 4096) / 1024 / 1024);
    return 0;
}
