/*
 * 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 <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>

#include <android/log.h>
#include <log/event_tag_map.h>

#include "log_portability.h"

#define OUT_TAG "EventTagMap"

/*
 * Single entry.
 */
typedef struct EventTag {
    uint32_t tagIndex;
    char*    tagStr;
    size_t   tagLen;
    char*    fmtStr;
    size_t   fmtLen;
} 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);

/*
 * 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'.
 */
LIBLOG_ABI_PUBLIC EventTagMap* android_openEventTagMap(const char* fileName)
{
    EventTagMap* newTagMap;
    off_t end;
    int save_errno;
    const char* tagfile = fileName ? fileName : EVENT_TAG_MAP_FILE;

    int fd = open(tagfile, O_RDONLY | O_CLOEXEC);
    if (fd < 0) {
        save_errno = errno;
        fprintf(stderr, "%s: unable to open map '%s': %s\n",
                OUT_TAG, tagfile, strerror(save_errno));
        goto fail_errno;
    }

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

    newTagMap = (EventTagMap*)calloc(1, sizeof(EventTagMap));
    if (newTagMap == NULL) {
        save_errno = errno;
        goto fail_close;
    }

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

    newTagMap->mapLen = end;

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

    return newTagMap;

fail_unmap:
    munmap(newTagMap->mapAddr, newTagMap->mapLen);
    save_errno = EINVAL;
fail_free:
    free(newTagMap);
fail_close:
    close(fd);
fail_errno:
    errno = save_errno;
fail:
    return NULL;
}

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

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

/*
 * Look up an entry in the map.
 *
 * The entries are sorted by tag number, so we can do a binary search.
 */
LIBLOG_ABI_PUBLIC const char* android_lookupEventTag_len(const EventTagMap* map,
                                                         size_t *len,
                                                         unsigned int tag)
{
    int lo = 0;
    int hi = map->numTags - 1;

    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        int 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 */
            if (len) *len = map->tagArray[mid].tagLen;
            /*
             * b/31456426 to check if gTest can detect copy-on-write issue
             * add the following line to break us:
             *     map->tagArray[mid].tagStr[map->tagArray[mid].tagLen] = '\0';
             * or explicitly use deprecated android_lookupEventTag().
             */
            return map->tagArray[mid].tagStr;
        }
    }

    errno = ENOENT;
    if (len) *len = 0;
    return NULL;
}

/*
 * Look up an entry in the map.
 *
 * The entries are sorted by tag number, so we can do a binary search.
 */
LIBLOG_ABI_PUBLIC const char* android_lookupEventFormat_len(
    const EventTagMap* map, size_t *len, unsigned int tag)
{
    int lo = 0;
    int hi = map->numTags - 1;

    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        int 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 */
            if (len) *len = map->tagArray[mid].fmtLen;
            return map->tagArray[mid].fmtStr;
        }
    }

    errno = ENOENT;
    if (len) *len = 0;
    return NULL;
}

LIBLOG_ABI_PUBLIC const char* android_lookupEventTag(const EventTagMap* map,
                                                     unsigned int tag)
{
    size_t len;
    const char* tagStr = android_lookupEventTag_len(map, &len, tag);
    char* cp;

    if (!tagStr) return tagStr;
    cp = (char*)tagStr;
    cp += len;
    if (*cp) *cp = '\0'; /* Trigger copy on write :-( */
    return tagStr;
}

/*
 * Crunch through the file, parsing the contents and creating a tag index.
 */
static int processFile(EventTagMap* map)
{
    /* get a tag count */
    map->numTags = countMapLines(map);
    if (map->numTags < 0) {
        errno = ENOENT;
        return -1;
    }

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

    /* parse the file, null-terminating tag strings */
    if (parseMapLines(map) != 0) 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)
{
    const char* cp = (const char*) map->mapAddr;
    const char* endp = cp + map->mapLen;
    int numTags = 0;
    int unknown = 1;

    while (cp < endp) {
        if (*cp == '\n') {
            unknown = 1;
        } else if (unknown) {
            if (isdigit(*cp)) {
                /* looks like a tag to me */
                numTags++;
                unknown = 0;
            } else if (isspace(*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*) map->mapAddr;
    char* 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);
        errno = EINVAL;
        return -1;
    }

    tagNum = 0;
    lineStart = 1;
    lineNum = 1;
    while (cp < endp) {
        if (*cp == '\n') {
            lineStart = 1;
            lineNum++;
        } else if (lineStart) {
            if (*cp == '#') {
                /* comment; just scan to end */
                lineStart = 0;
            } else if (isdigit(*cp)) {
                /* looks like a tag; scan it out */
                if (tagNum >= map->numTags) {
                    fprintf(stderr,
                        "%s: more tags than expected (%d)\n", OUT_TAG, tagNum);
                    errno = EMFILE;
                    return -1;
                }
                if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0) {
                    return -1;
                }
                tagNum++;
                lineNum++;      // we eat the '\n'
                /* leave lineStart==1 */
            } else if (isspace(*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);
                errno = EINVAL;
                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);
        errno = EINVAL;
        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;

    unsigned long val = strtoul(*pData, &cp, 10);
    if (cp == *pData) {
        fprintf(stderr, "%s: malformed tag number on line %d\n", OUT_TAG, lineNum);
        errno = EINVAL;
        return -1;
    }

    tag->tagIndex = val;
    if (tag->tagIndex != val) {
        fprintf(stderr, "%s: tag number too large on line %d\n", OUT_TAG, lineNum);
        errno = ERANGE;
        return -1;
    }

    while ((*++cp != '\n') && isspace(*cp)) {
    }

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

    tag->tagStr = cp;

    /* Determine whether "c" is a valid tag char. */
    while (isalnum(*++cp) || (*cp == '_')) {
    }
    tag->tagLen = cp - tag->tagStr;

    if (!isspace(*cp)) {
        fprintf(stderr, "%s: invalid tag chars on line %d\n", OUT_TAG, lineNum);
        errno = EINVAL;
        return -1;
    }

    while (isspace(*cp) && (*cp != '\n')) ++cp;
    if (*cp != '#') {
        tag->fmtStr = cp;
        while ((*cp != '\n') && (*cp != '#')) ++cp;
        while ((cp > tag->fmtStr) && isspace(*(cp - 1))) --cp;
        tag->fmtLen = cp - tag->fmtStr;
    }

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

    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 (%" PRIu32 ":%.*s:%.*s and %" PRIu32 ":%.*s:%.*s)\n",
                OUT_TAG,
                map->tagArray[i].tagIndex,
                (int)map->tagArray[i].tagLen, map->tagArray[i].tagStr,
                (int)map->tagArray[i].fmtLen, map->tagArray[i].fmtStr,
                map->tagArray[i - 1].tagIndex,
                (int)map->tagArray[i - 1].tagLen, map->tagArray[i - 1].fmtStr,
                (int)map->tagArray[i - 1].fmtLen, map->tagArray[i - 1].fmtStr);
            errno = EMLINK;
            return -1;
        }
    }

    return 0;
}
