/*
 * 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.
 */

#define LOG_TAG "memtrack"

#include <memtrack/memtrack.h>

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

#include <hardware/memtrack.h>
#include <log/log.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);
}
