/*
 * Copyright (C) 2008 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 <stdlib.h>
#include <string.h>

#include <pagemap/pagemap.h>

int pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len) {
    if (!map)
        return -1;

    return pm_process_pagemap_range(map->proc, map->start, map->end,
                                    pagemap_out, len);
}

int pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out,
                        uint64_t flags_mask, uint64_t required_flags) {
    uint64_t *pagemap;
    size_t len, i;
    uint64_t count;
    pm_memusage_t usage;
    int error;

    if (!map || !usage_out)
        return -1;

    error = pm_map_pagemap(map, &pagemap, &len);
    if (error) return error;

    pm_memusage_zero(&usage);
    pm_memusage_pswap_init_handle(&usage, usage_out->p_swap);

    for (i = 0; i < len; i++) {
        usage.vss += map->proc->ker->pagesize;

        if (!PM_PAGEMAP_PRESENT(pagemap[i]) &&
                !PM_PAGEMAP_SWAPPED(pagemap[i]))
            continue;

        if (!PM_PAGEMAP_SWAPPED(pagemap[i])) {
            if (flags_mask) {
                uint64_t flags;
                error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
                                        &flags);
                if (error) goto out;

                if ((flags & flags_mask) != required_flags)
                    continue;
            }

            error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
                                    &count);
            if (error) goto out;

            usage.rss += (count >= 1) ? map->proc->ker->pagesize : (0);
            usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
            usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
        } else {
            usage.swap += map->proc->ker->pagesize;
            pm_memusage_pswap_add_offset(&usage, PM_PAGEMAP_SWAP_OFFSET(pagemap[i]));
        }
    }

    memcpy(usage_out, &usage, sizeof(usage));

    error = 0;

out:
    free(pagemap);

    return error;
}

int pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out) {
    return pm_map_usage_flags(map, usage_out, 0, 0);
}

int pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out) {
    uint64_t *pagemap;
    size_t len, i;
    uint64_t count, flags;
    pm_memusage_t ws;
    int error;

    if (!map || !ws_out)
        return -1;

    error = pm_map_pagemap(map, &pagemap, &len);
    if (error) return error;

    pm_memusage_zero(&ws);

    for (i = 0; i < len; i++) {
        error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
                                &flags);
        if (error) goto out;

        if (!(flags & KPF_REFERENCED))
            continue;

        error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
                                &count);
        if (error) goto out;

        ws.vss += map->proc->ker->pagesize;
        if( PM_PAGEMAP_SWAPPED(pagemap[i]) ) continue;
        ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0);
        ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
        ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
    }

    memcpy(ws_out, &ws, sizeof(ws));

    error = 0;

out:
    free(pagemap);

    return 0;
}

int pm_map_destroy(pm_map_t *map) {
    if (!map)
        return -1;

    free(map->name);
    free(map);

    return 0;
}
