/*
 * Copyright 2015, Intel Corporation
 * Copyright (C) 2015 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.
 *
 * Written by William Roberts <william.c.roberts@intel.com>
 *
 */

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/limits.h>

#define LOG_TAG "packagelistparser"
#include <cutils/log.h>

#include <packagelistparser/packagelistparser.h>

#define CLOGE(fmt, ...) \
    do {\
        IF_ALOGE() {\
            ALOGE(fmt, ##__VA_ARGS__);\
        }\
    } while(0)

static size_t get_gid_cnt(const char *gids)
{
    size_t cnt;

    if (*gids == '\0') {
        return 0;
    }

    if (!strcmp(gids, "none")) {
        return 0;
    }

    for (cnt = 1; gids[cnt]; gids[cnt] == ',' ? cnt++ : *gids++)
        ;

    return cnt;
}

static bool parse_gids(char *gids, gid_t *gid_list, size_t *cnt)
{
    gid_t gid;
    char* token;
    char *endptr;
    size_t cmp = 0;

    while ((token = strsep(&gids, ",\r\n"))) {

        if (cmp > *cnt) {
            return false;
        }

        gid = strtoul(token, &endptr, 10);
        if (*endptr != '\0') {
            return false;
        }

        /*
         * if unsigned long is greater than size of gid_t,
         * prevent a truncation based roll-over
         */
        if (gid > GID_MAX) {
            CLOGE("A gid in field \"gid list\" greater than GID_MAX");
            return false;
        }

        gid_list[cmp++] = gid;
    }
    return true;
}

extern bool packagelist_parse(pfn_on_package callback, void *userdata)
{

    FILE *fp;
    char *cur;
    char *next;
    char *endptr;
    unsigned long tmp;
    ssize_t bytesread;

    bool rc = false;
    char *buf = NULL;
    size_t buflen = 0;
    unsigned long lineno = 1;
    const char *errmsg = NULL;
    struct pkg_info *pkg_info = NULL;

    fp = fopen(PACKAGES_LIST_FILE, "re");
    if (!fp) {
        CLOGE("Could not open: \"%s\", error: \"%s\"\n", PACKAGES_LIST_FILE,
                strerror(errno));
        return false;
    }

    while ((bytesread = getline(&buf, &buflen, fp)) > 0) {

        pkg_info = calloc(1, sizeof(*pkg_info));
        if (!pkg_info) {
            goto err;
        }

        next = buf;

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for \"package name\"";
            goto err;
        }

        pkg_info->name = strdup(cur);
        if (!pkg_info->name) {
            goto err;
        }

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for field \"uid\"";
            goto err;
        }

        tmp = strtoul(cur, &endptr, 10);
        if (*endptr != '\0') {
            errmsg = "Could not convert field \"uid\" to integer value";
            goto err;
        }

        /*
         * if unsigned long is greater than size of uid_t,
         * prevent a truncation based roll-over
         */
        if (tmp > UID_MAX) {
            errmsg = "Field \"uid\" greater than UID_MAX";
            goto err;
        }

        pkg_info->uid = (uid_t) tmp;

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for field \"debuggable\"";
            goto err;
        }

        tmp = strtoul(cur, &endptr, 10);
        if (*endptr != '\0') {
            errmsg = "Could not convert field \"debuggable\" to integer value";
            goto err;
        }

        /* should be a valid boolean of 1 or 0 */
        if (!(tmp == 0 || tmp == 1)) {
            errmsg = "Field \"debuggable\" is not 0 or 1 boolean value";
            goto err;
        }

        pkg_info->debuggable = (bool) tmp;

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for field \"data dir\"";
            goto err;
        }

        pkg_info->data_dir = strdup(cur);
        if (!pkg_info->data_dir) {
            goto err;
        }

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for field \"seinfo\"";
            goto err;
        }

        pkg_info->seinfo = strdup(cur);
        if (!pkg_info->seinfo) {
            goto err;
        }

        cur = strsep(&next, " \t\r\n");
        if (!cur) {
            errmsg = "Could not get next token for field \"gid(s)\"";
            goto err;
        }

        /*
         * Parse the gid list, could be in the form of none, single gid or list:
         * none
         * gid
         * gid, gid ...
         */
        pkg_info->gids.cnt = get_gid_cnt(cur);
        if (pkg_info->gids.cnt > 0) {

            pkg_info->gids.gids = calloc(pkg_info->gids.cnt, sizeof(gid_t));
            if (!pkg_info->gids.gids) {
                goto err;
            }

            rc = parse_gids(cur, pkg_info->gids.gids, &pkg_info->gids.cnt);
            if (!rc) {
                errmsg = "Could not parse field \"gid list\"";
                goto err;
            }
        }

        rc = callback(pkg_info, userdata);
        if (rc == false) {
            /*
             * We do not log this as this can be intentional from
             * callback to abort processing. We go to out to not
             * free the pkg_info
             */
            rc = true;
            goto out;
        }
        lineno++;
    }

    rc = true;

out:
    free(buf);
    fclose(fp);
    return rc;

err:
    if (errmsg) {
        CLOGE("Error Parsing \"%s\" on line: %lu for reason: %s",
                PACKAGES_LIST_FILE, lineno, errmsg);
    }
    rc = false;
    packagelist_free(pkg_info);
    goto out;
}

void packagelist_free(pkg_info *info)
{
    if (info) {
        free(info->name);
        free(info->data_dir);
        free(info->seinfo);
        free(info->gids.gids);
        free(info);
    }
}
