/*
 * Copyright (C) 2007 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 "cutils/event_tag_map.h"
#include "cutils/log.h"

#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <assert.h>

#define OUT_TAG "EventTagMap"

/*
 * Single entry.
 */
typedef struct EventTag {
    unsigned int    tagIndex;
    const char*     tagStr;
} EventTag;

/*
 * Map.
 */
struct EventTagMap {
    /* memory-mapped source file; we get strings from here */
    void*           mapAddr;
    size_t          mapLen;

    /* array of event tags, sorted numerically by tag index */
    EventTag*       tagArray;
    int             numTags;
};

/* fwd */
static int processFile(EventTagMap* map);
static int countMapLines(const EventTagMap* map);
static int parseMapLines(EventTagMap* map);
static int scanTagLine(char** pData, EventTag* tag, int lineNum);
static int sortTags(EventTagMap* map);
static void dumpTags(const EventTagMap* map);


/*
 * Open the map file and allocate a structure to manage it.
 *
 * We create a private mapping because we want to terminate the log tag
 * strings with '\0'.
 */
EventTagMap* android_openEventTagMap(const char* fileName)
{
    EventTagMap* newTagMap;
    off_t end;
    int fd = -1;

    newTagMap = calloc(1, sizeof(EventTagMap));
    if (newTagMap == NULL)
        return NULL;

    fd = open(fileName, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "%s: unable to open map '%s': %s\n",
            OUT_TAG, fileName, strerror(errno));
        goto fail;
    }

    end = lseek(fd, 0L, SEEK_END);
    (void) lseek(fd, 0L, SEEK_SET);
    if (end < 0) {
        fprintf(stderr, "%s: unable to seek map '%s'\n", OUT_TAG, fileName);
        goto fail;
    }

    newTagMap->mapAddr = mmap(NULL, end, PROT_READ | PROT_WRITE, MAP_PRIVATE,
                                fd, 0);
    if (newTagMap->mapAddr == MAP_FAILED) {
        fprintf(stderr, "%s: mmap(%s) failed: %s\n",
            OUT_TAG, fileName, strerror(errno));
        goto fail;
    }
    newTagMap->mapLen = end;

    if (processFile(newTagMap) != 0)
        goto fail;

    return newTagMap;

fail:
    android_closeEventTagMap(newTagMap);
    if (fd >= 0)
        close(fd);
    return NULL;
}

/*
 * Close the map.
 */
void android_closeEventTagMap(EventTagMap* map)
{
    if (map == NULL)
        return;

    munmap(map->mapAddr, map->mapLen);
    free(map);
}

/*
 * Look up an entry in the map.
 *
 * The entries are sorted by tag number, so we can do a binary search.
 */
const char* android_lookupEventTag(const EventTagMap* map, int tag)
{
    int hi, lo, mid;

    lo = 0;
    hi = map->numTags-1;

    while (lo <= hi) {
        int cmp;

        mid = (lo+hi)/2;
        cmp = map->tagArray[mid].tagIndex - tag;
        if (cmp < 0) {
            /* tag is bigger */
            lo = mid + 1;
        } else if (cmp > 0) {
            /* tag is smaller */
            hi = mid - 1;
        } else {
            /* found */
            return map->tagArray[mid].tagStr;
        }
    }

    return NULL;
}



/*
 * Determine whether "c" is a whitespace char.
 */
static inline int isCharWhitespace(char c)
{
    return (c == ' ' || c == '\n' || c == '\r' || c == '\t');
}

/*
 * Determine whether "c" is a valid tag char.
 */
static inline int isCharValidTag(char c)
{
    return ((c >= 'A' && c <= 'Z') ||
            (c >= 'a' && c <= 'z') ||
            (c >= '0' && c <= '9') ||
            (c == '_'));
}

/*
 * Determine whether "c" is a valid decimal digit.
 */
static inline int isCharDigit(char c)
{
    return (c >= '0' && c <= '9');
}


/*
 * Crunch through the file, parsing the contents and creating a tag index.
 */
static int processFile(EventTagMap* map)
{
    EventTag* tagArray = NULL;

    /* get a tag count */
    map->numTags = countMapLines(map);
    if (map->numTags < 0)
        return -1;

    //printf("+++ found %d tags\n", map->numTags);

    /* allocate storage for the tag index array */
    map->tagArray = calloc(1, sizeof(EventTag) * map->numTags);
    if (map->tagArray == NULL)
        return -1;

    /* parse the file, null-terminating tag strings */
    if (parseMapLines(map) != 0) {
        fprintf(stderr, "%s: file parse failed\n", OUT_TAG);
        return -1;
    }

    /* sort the tags and check for duplicates */
    if (sortTags(map) != 0)
        return -1;

    return 0;
}

/*
 * Run through all lines in the file, determining whether they're blank,
 * comments, or possibly have a tag entry.
 *
 * This is a very "loose" scan.  We don't try to detect syntax errors here.
 * The later pass is more careful, but the number of tags found there must
 * match the number of tags found here.
 *
 * Returns the number of potential tag entries found.
 */
static int countMapLines(const EventTagMap* map)
{
    int numTags, unknown;
    const char* cp;
    const char* endp;

    cp = (const char*) map->mapAddr;
    endp = cp + map->mapLen;

    numTags = 0;
    unknown = 1;
    while (cp < endp) {
        if (*cp == '\n') {
            unknown = 1;
        } else if (unknown) {
            if (isCharDigit(*cp)) {
                /* looks like a tag to me */
                numTags++;
                unknown = 0;
            } else if (isCharWhitespace(*cp)) {
                /* might be leading whitespace before tag num, keep going */
            } else {
                /* assume comment; second pass can complain in detail */
                unknown = 0;
            }
        } else {
            /* we've made up our mind; just scan to end of line */
        }
        cp++;
    }

    return numTags;
}

/*
 * Parse the tags out of the file.
 */
static int parseMapLines(EventTagMap* map)
{
    int tagNum, lineStart, lineNum;
    char* cp;
    char* endp;

    cp = (char*) map->mapAddr;
    endp = cp + map->mapLen;

    /* insist on EOL at EOF; simplifies parsing and null-termination */
    if (*(endp-1) != '\n') {
        fprintf(stderr, "%s: map file missing EOL on last line\n", OUT_TAG);
        return -1;
    }

    tagNum = 0;
    lineStart = 1;
    lineNum = 1;
    while (cp < endp) {
        //printf("{%02x}", *cp); fflush(stdout);
        if (*cp == '\n') {
            lineStart = 1;
            lineNum++;
        } else if (lineStart) {
            if (*cp == '#') {
                /* comment; just scan to end */
                lineStart = 0;
            } else if (isCharDigit(*cp)) {
                /* looks like a tag; scan it out */
                if (tagNum >= map->numTags) {
                    fprintf(stderr,
                        "%s: more tags than expected (%d)\n", OUT_TAG, tagNum);
                    return -1;
                }
                if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0)
                    return -1;
                tagNum++;
                lineNum++;      // we eat the '\n'
                /* leave lineStart==1 */
            } else if (isCharWhitespace(*cp)) {
                /* looks like leading whitespace; keep scanning */
            } else {
                fprintf(stderr,
                    "%s: unexpected chars (0x%02x) in tag number on line %d\n",
                    OUT_TAG, *cp, lineNum);
                return -1;
            }
        } else {
            /* this is a blank or comment line */
        }
        cp++;
    }

    if (tagNum != map->numTags) {
        fprintf(stderr, "%s: parsed %d tags, expected %d\n",
            OUT_TAG, tagNum, map->numTags);
        return -1;
    }

    return 0;
}

/*
 * Scan one tag line.
 *
 * "*pData" should be pointing to the first digit in the tag number.  On
 * successful return, it will be pointing to the last character in the
 * tag line (i.e. the character before the start of the next line).
 *
 * Returns 0 on success, nonzero on failure.
 */
static int scanTagLine(char** pData, EventTag* tag, int lineNum)
{
    char* cp = *pData;
    char* startp;
    char* endp;
    unsigned long val;

    startp = cp;
    while (isCharDigit(*++cp))
        ;
    *cp = '\0';

    val = strtoul(startp, &endp, 10);
    assert(endp == cp);
    if (endp != cp)
        fprintf(stderr, "ARRRRGH\n");

    tag->tagIndex = val;

    while (*++cp != '\n' && isCharWhitespace(*cp))
        ;

    if (*cp == '\n') {
        fprintf(stderr,
            "%s: missing tag string on line %d\n", OUT_TAG, lineNum);
        return -1;
    }

    tag->tagStr = cp;

    while (isCharValidTag(*++cp))
        ;

    if (*cp == '\n') {
        /* null terminate and return */
        *cp = '\0';
    } else if (isCharWhitespace(*cp)) {
        /* CRLF or trailin spaces; zap this char, then scan for the '\n' */
        *cp = '\0';

        /* just ignore the rest of the line till \n
        TODO: read the tag description that follows the tag name
        */
        while (*++cp != '\n') {
        }
    } else {
        fprintf(stderr,
            "%s: invalid tag chars on line %d\n", OUT_TAG, lineNum);
        return -1;
    }

    *pData = cp;

    //printf("+++ Line %d: got %d '%s'\n", lineNum, tag->tagIndex, tag->tagStr);
    return 0;
}

/*
 * Compare two EventTags.
 */
static int compareEventTags(const void* v1, const void* v2)
{
    const EventTag* tag1 = (const EventTag*) v1;
    const EventTag* tag2 = (const EventTag*) v2;

    return tag1->tagIndex - tag2->tagIndex;
}

/*
 * Sort the EventTag array so we can do fast lookups by tag index.  After
 * the sort we do a quick check for duplicate tag indices.
 *
 * Returns 0 on success.
 */
static int sortTags(EventTagMap* map)
{
    int i;

    qsort(map->tagArray, map->numTags, sizeof(EventTag), compareEventTags);

    for (i = 1; i < map->numTags; i++) {
        if (map->tagArray[i].tagIndex == map->tagArray[i-1].tagIndex) {
            fprintf(stderr, "%s: duplicate tag entries (%d:%s and %d:%s)\n",
                OUT_TAG,
                map->tagArray[i].tagIndex, map->tagArray[i].tagStr,
                map->tagArray[i-1].tagIndex, map->tagArray[i-1].tagStr);
            return -1;
        }
    }

    return 0;
}

/*
 * Dump the tag array for debugging.
 */
static void dumpTags(const EventTagMap* map)
{
    int i;

    for (i = 0; i < map->numTags; i++) {
        const EventTag* tag = &map->tagArray[i];
        printf("  %3d: %6d '%s'\n", i, tag->tagIndex, tag->tagStr);
    }
}

