/*
 * Copyright (C) 2013 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 <memtrack/memtrack.h>

#define LOG_TAG "memtrack"

#include <log/log.h>

#include <errno.h>
#include <malloc.h>
#include <string.h>

#include <hardware/memtrack.h>

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

static const memtrack_module_t *module;

struct memtrack_proc {
    pid_t pid;
    struct memtrack_proc_type {
        enum memtrack_type type;
        size_t num_records;
        size_t allocated_records;
        struct memtrack_record *records;
    } types[MEMTRACK_NUM_TYPES];
};

int memtrack_init(void)
{
    int err;

    if (module) {
        return 0;
    }

    err = hw_get_module(MEMTRACK_HARDWARE_MODULE_ID,
            (hw_module_t const**)&module);
    if (err) {
        ALOGE("Couldn't load %s module (%s)", MEMTRACK_HARDWARE_MODULE_ID,
                strerror(-err));
        return err;
    }

    return module->init(module);
}

struct memtrack_proc *memtrack_proc_new(void)
{
    if (!module) {
        return NULL;
    }

    return calloc(sizeof(struct memtrack_proc), 1);
}

void memtrack_proc_destroy(struct memtrack_proc *p)
{
    enum memtrack_type i;

    if (p) {
        for (i = 0; i < MEMTRACK_NUM_TYPES; i++) {
            free(p->types[i].records);
        }
    }
    free(p);
}

static int memtrack_proc_get_type(struct memtrack_proc_type *t,
            pid_t pid, enum memtrack_type type)
{
    size_t num_records = t->num_records;
    int ret;

retry:
    ret = module->getMemory(module, pid, type, t->records, &num_records);
    if (ret) {
        t->num_records = 0;
        return ret;
    }
    if (num_records > t->allocated_records) {
        /* Need more records than allocated */
        free(t->records);
        t->records = calloc(sizeof(*t->records), num_records);
        if (!t->records) {
            return -ENOMEM;
        }
        t->allocated_records = num_records;
        goto retry;
    }
    t->num_records = num_records;

    return 0;
}

/* TODO: sanity checks on return values from HALs:
 *   make sure no records have invalid flags set
 *    - unknown flags
 *    - too many flags of a single category
 *    - missing ACCOUNTED/UNACCOUNTED
 *   make sure there are not overlapping SHARED and SHARED_PSS records
 */
static int memtrack_proc_sanity_check(struct memtrack_proc *p)
{
    (void)p;
    return 0;
}

int memtrack_proc_get(struct memtrack_proc *p, pid_t pid)
{
    enum memtrack_type i;

    if (!module) {
        return -EINVAL;
    }

    if (!p) {
        return -EINVAL;
    }

    p->pid = pid;
    for (i = 0; i < MEMTRACK_NUM_TYPES; i++) {
        memtrack_proc_get_type(&p->types[i], pid, i);
    }

    return memtrack_proc_sanity_check(p);
}

static ssize_t memtrack_proc_sum(struct memtrack_proc *p,
            enum memtrack_type types[], size_t num_types,
            unsigned int flags)
{
    ssize_t sum = 0;
    size_t i;
    size_t j;

    for (i = 0; i < num_types; i++) {
        enum memtrack_type type = types[i];
        for (j = 0; j < p->types[type].num_records; j++) {
            if ((p->types[type].records[j].flags & flags) == flags) {
                sum += p->types[type].records[j].size_in_bytes;
            }
        }
    }

    return sum;
}

ssize_t memtrack_proc_graphics_total(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_GRAPHICS };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types), 0);
}

ssize_t memtrack_proc_graphics_pss(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_GRAPHICS };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types),
                MEMTRACK_FLAG_SMAPS_UNACCOUNTED);
}

ssize_t memtrack_proc_gl_total(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_GL };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types), 0);
}

ssize_t memtrack_proc_gl_pss(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_GL };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types),
                MEMTRACK_FLAG_SMAPS_UNACCOUNTED);
}

ssize_t memtrack_proc_other_total(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_MULTIMEDIA,
                                        MEMTRACK_TYPE_CAMERA,
                                        MEMTRACK_TYPE_OTHER };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types), 0);
}

ssize_t memtrack_proc_other_pss(struct memtrack_proc *p)
{
    enum memtrack_type types[] = { MEMTRACK_TYPE_MULTIMEDIA,
                                        MEMTRACK_TYPE_CAMERA,
                                        MEMTRACK_TYPE_OTHER };
    return memtrack_proc_sum(p, types, ARRAY_SIZE(types),
                MEMTRACK_FLAG_SMAPS_UNACCOUNTED);
}
