/*
 * Copyright (C) 2017 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 <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>

#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <log/log_event_list.h>
#include <log/log_properties.h>
#include <private/android_filesystem_config.h>

#include "LogTags.h"
#include "LogUtils.h"

using android::base::make_scope_guard;

static LogTags* logtags;

const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags";
const char LogTags::dynamic_event_log_tags[] = "/dev/event-log-tags";
// Only for debug
const char LogTags::debug_event_log_tags[] = "/data/misc/logd/event-log-tags";

// Sniff for first uid=%d in utf8z comment string
static uid_t sniffUid(const char* comment, const char* endp) {
    if (!comment) return AID_ROOT;

    if (*comment == '#') ++comment;
    while ((comment < endp) && (*comment != '\n') && isspace(*comment))
        ++comment;
    static const char uid_str[] = "uid=";
    if (((comment + strlen(uid_str)) >= endp) ||
        fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) ||
        !isdigit(comment[strlen(uid_str)]))
        return AID_ROOT;
    char* cp;
    unsigned long Uid = strtoul(comment + 4, &cp, 10);
    if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT;

    return Uid;
}

// Checks for file corruption, and report false if there was no need
// to rebuild the referenced file.  Failure to rebuild is only logged,
// does not cause a return value of false.
bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) {
    int fd;

    {
        android::RWLock::AutoRLock readLock(rwlock);

        if (tag2total.begin() == tag2total.end()) {
            return false;
        }

        file2watermark_const_iterator iwater = file2watermark.find(filename);
        if (iwater == file2watermark.end()) {
            return false;
        }

        struct stat sb;
        if (!stat(filename, &sb) && ((size_t)sb.st_size >= iwater->second)) {
            return false;
        }

        // dump what we already know back into the file?
        fd = TEMP_FAILURE_RETRY(open(
            filename, O_WRONLY | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY));
        if (fd >= 0) {
            time_t now = time(nullptr);
            struct tm tm;
            localtime_r(&now, &tm);
            char timebuf[20];
            size_t len =
                strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", &tm);
            android::base::WriteStringToFd(
                android::base::StringPrintf(
                    "# Rebuilt %.20s, content owned by logd\n", timebuf),
                fd);
            for (const auto& it : tag2total) {
                android::base::WriteStringToFd(
                    formatEntry_locked(it.first, AID_ROOT), fd);
            }
            close(fd);
        }
    }

    if (warn) {
        android::prdebug(
            ((fd < 0) ? "%s failed to rebuild"
                      : "%s missing, damaged or truncated; rebuilt"),
            filename);
    }

    if (fd >= 0) {
        android::RWLock::AutoWLock writeLock(rwlock);

        struct stat sb;
        if (!stat(filename, &sb)) file2watermark[filename] = sb.st_size;
    }

    return true;
}

void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name,
                              const std::string& Format, const char* source,
                              bool warn) {
    std::string Key = Name;
    if (Format.length()) Key += "+" + Format;

    bool update = !source || !!strcmp(source, system_event_log_tags);
    bool newOne;

    {
        android::RWLock::AutoWLock writeLock(rwlock);

        tag2total_const_iterator itot = tag2total.find(tag);

        // unlikely except for dupes, or updates to uid list (more later)
        if (itot != tag2total.end()) update = false;

        newOne = tag2name.find(tag) == tag2name.end();
        key2tag[Key] = tag;

        if (Format.length()) {
            if (key2tag.find(Name) == key2tag.end()) {
                key2tag[Name] = tag;
            }
            tag2format[tag] = Format;
        }
        tag2name[tag] = Name;

        tag2uid_const_iterator ut = tag2uid.find(tag);
        if (ut != tag2uid.end()) {
            if (uid == AID_ROOT) {
                tag2uid.erase(ut);
                update = true;
            } else if (ut->second.find(uid) == ut->second.end()) {
                const_cast<uid_list&>(ut->second).emplace(uid);
                update = true;
            }
        } else if (newOne && (uid != AID_ROOT)) {
            tag2uid[tag].emplace(uid);
            update = true;
        }

        // updatePersist -> trigger output on modified
        // content, reset tag2total if available
        if (update && (itot != tag2total.end())) tag2total[tag] = 0;
    }

    if (update) {
        WritePersistEventLogTags(tag, uid, source);
    } else if (warn && !newOne && source) {
        // For the files, we want to report dupes.
        android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag, Name.c_str(),
                         Format.c_str(), source);
    }
}

// Read the event log tags file, and build up our internal database
void LogTags::ReadFileEventLogTags(const char* filename, bool warn) {
    bool etc = !strcmp(filename, system_event_log_tags);
    bool debug = !etc && !strcmp(filename, debug_event_log_tags);

    if (!etc) {
        RebuildFileEventLogTags(filename, warn);
    }
    std::string content;
    if (android::base::ReadFileToString(filename, &content)) {
        char* cp = (char*)content.c_str();
        char* endp = cp + content.length();

        {
            android::RWLock::AutoRLock writeLock(rwlock);

            file2watermark[filename] = content.length();
        }

        char* lineStart = cp;
        while (cp < endp) {
            if (*cp == '\n') {
                lineStart = cp;
            } else if (lineStart) {
                if (*cp == '#') {
                    /* comment; just scan to end */
                    lineStart = nullptr;
                } else if (isdigit(*cp)) {
                    unsigned long Tag = strtoul(cp, &cp, 10);
                    if (warn && (Tag > emptyTag)) {
                        android::prdebug("tag too large %lu", Tag);
                    }
                    while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp;
                    if (cp >= endp) break;
                    if (*cp == '\n') continue;
                    const char* name = cp;
                    /* Determine whether it is a valid tag name [a-zA-Z0-9_] */
                    bool hasAlpha = false;
                    while ((cp < endp) && (isalnum(*cp) || (*cp == '_'))) {
                        if (!isdigit(*cp)) hasAlpha = true;
                        ++cp;
                    }
                    std::string Name(name, cp - name);
#ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT
                    static const size_t maximum_official_tag_name_size = 24;
                    if (warn &&
                        (Name.length() > maximum_official_tag_name_size)) {
                        android::prdebug("tag name too long %s", Name.c_str());
                    }
#endif
                    if (hasAlpha &&
                        ((cp >= endp) || (*cp == '#') || isspace(*cp))) {
                        if (Tag > emptyTag) {
                            if (*cp != '\n') lineStart = nullptr;
                            continue;
                        }
                        while ((cp < endp) && (*cp != '\n') && isspace(*cp))
                            ++cp;
                        const char* format = cp;
                        uid_t uid = AID_ROOT;
                        while ((cp < endp) && (*cp != '\n')) {
                            if (*cp == '#') {
                                uid = sniffUid(cp, endp);
                                lineStart = nullptr;
                                break;
                            }
                            ++cp;
                        }
                        while ((cp > format) && isspace(cp[-1])) {
                            --cp;
                            lineStart = nullptr;
                        }
                        std::string Format(format, cp - format);

                        AddEventLogTags((uint32_t)Tag, uid, Name, Format,
                                        filename, warn);
                    } else {
                        if (warn) {
                            android::prdebug("tag name invalid %.*s",
                                             (int)(cp - name + 1), name);
                        }
                        lineStart = nullptr;
                    }
                } else if (!isspace(*cp)) {
                    break;
                }
            }
            cp++;
        }
    } else if (warn) {
        android::prdebug("Cannot read %s", filename);
    }
}

// Extract a 4-byte value from a byte stream.
static inline uint32_t get4LE(const char* msg) {
    const uint8_t* src = reinterpret_cast<const uint8_t*>(msg);
    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}

// Additional persistent sources for invented log tags.  Read the
// special pmsg event for log tags, and build up our internal
// database with any found.
void LogTags::ReadPersistEventLogTags() {
    struct logger_list* logger_list = android_logger_list_alloc(
        ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0,
        (pid_t)0);
    if (!logger_list) return;

    struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS);
    struct logger* s = android_logger_open(logger_list, LOG_ID_SECURITY);
    if (!e && !s) {
        android_logger_list_free(logger_list);
        return;
    }

    for (;;) {
        struct log_msg log_msg;
        int ret = android_logger_list_read(logger_list, &log_msg);
        if (ret <= 0) break;

        const char* msg = log_msg.msg();
        if (!msg) continue;
        if (log_msg.entry.len <= sizeof(uint32_t)) continue;
        uint32_t Tag = get4LE(msg);
        if (Tag != TAG_DEF_LOG_TAG) continue;
        uid_t uid = log_msg.entry.uid;

        std::string Name;
        std::string Format;
        android_log_list_element elem;
        {
            auto ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
                                                 log_msg.entry.len - sizeof(uint32_t));
            auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
            elem = android_log_read_next(ctx);
            if (elem.type != EVENT_TYPE_LIST) {
                continue;
            }
            elem = android_log_read_next(ctx);
            if (elem.type != EVENT_TYPE_INT) {
                continue;
            }
            Tag = elem.data.int32;
            elem = android_log_read_next(ctx);
            if (elem.type != EVENT_TYPE_STRING) {
                continue;
            }
            Name = std::string(elem.data.string, elem.len);
            elem = android_log_read_next(ctx);
            if (elem.type != EVENT_TYPE_STRING) {
                continue;
            }
            Format = std::string(elem.data.string, elem.len);
            elem = android_log_read_next(ctx);
        }
        if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue;

        AddEventLogTags(Tag, uid, Name, Format);
    }
    android_logger_list_free(logger_list);
}

LogTags::LogTags() {
    ReadFileEventLogTags(system_event_log_tags);
    // Following will likely fail on boot, but is required if logd restarts
    ReadFileEventLogTags(dynamic_event_log_tags, false);
    if (__android_log_is_debuggable()) {
        ReadFileEventLogTags(debug_event_log_tags, false);
    }
    ReadPersistEventLogTags();

    logtags = this;
}

// Converts an event tag into a name
const char* LogTags::tagToName(uint32_t tag) const {
    tag2name_const_iterator it;

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    it = tag2name.find(tag);
    if ((it == tag2name.end()) || (it->second.length() == 0)) return nullptr;

    return it->second.c_str();
}

// Prototype in LogUtils.h allowing external access to our database.
//
// This must be a pure reader to our database, as everything else is
// guaranteed single-threaded except this access point which is
// asynchonous and can be multithreaded and thus rentrant.  The
// object's rwlock is only used to guarantee atomic access to the
// unordered_map to prevent corruption, with a requirement to be a
// low chance of contention for this call.  If we end up changing
// this algorithm resulting in write, then we should use a different
// lock than the object's rwlock to protect groups of associated
// actions.
const char* android::tagToName(uint32_t tag) {
    LogTags* me = logtags;

    if (!me) return nullptr;
    me->WritePmsgEventLogTags(tag);
    return me->tagToName(tag);
}

// Prototype in LogUtils.h allowing external access to our database.
//
// This only works on userdebug and eng devices to re-read the
// /data/misc/logd/event-log-tags file right after /data is mounted.
// The operation is near to boot and should only happen once.  There
// are races associated with its use since it can trigger a Rebuild
// of the file, but that is a can-not-happen since the file was not
// read yet.  More dangerous if called later, but if all is well it
// should just skip over everything and not write any new entries.
void android::ReReadEventLogTags() {
    LogTags* me = logtags;

    if (me && __android_log_is_debuggable()) {
        me->ReadFileEventLogTags(me->debug_event_log_tags);
    }
}

// converts an event tag into a format
const char* LogTags::tagToFormat(uint32_t tag) const {
    tag2format_const_iterator iform;

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    iform = tag2format.find(tag);
    if (iform == tag2format.end()) return nullptr;

    return iform->second.c_str();
}

// converts a name into an event tag
uint32_t LogTags::nameToTag(const char* name) const {
    uint32_t ret = emptyTag;

    // Bug: Only works for a single entry, we can have multiple entries,
    // one for each format, so we find first entry recorded, or entry with
    // no format associated with it.

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    key2tag_const_iterator ik = key2tag.find(std::string(name));
    if (ik != key2tag.end()) ret = ik->second;

    return ret;
}

// Caller must perform locks, can be under reader (for pre-check) or
// writer lock.  We use this call to invent a new deterministically
// random tag, unique is cleared if no conflicts.  If format is NULL,
// we are in readonly mode.
uint32_t LogTags::nameToTag_locked(const std::string& name, const char* format,
                                   bool& unique) {
    key2tag_const_iterator ik;

    bool write = format != nullptr;
    unique = write;

    if (!write) {
        // Bug: Only works for a single entry, we can have multiple entries,
        // one for each format, so we find first entry recorded, or entry with
        // no format associated with it.
        ik = key2tag.find(name);
        if (ik == key2tag.end()) return emptyTag;
        return ik->second;
    }

    std::string Key(name);
    if (*format) Key += std::string("+") + format;

    ik = key2tag.find(Key);
    if (ik != key2tag.end()) {
        unique = false;
        return ik->second;
    }

    size_t Hash = key2tag.hash_function()(Key);
    uint32_t Tag = Hash;
    // This sets an upper limit on the conflics we are allowed to deal with.
    for (unsigned i = 0; i < 256;) {
        tag2name_const_iterator it = tag2name.find(Tag);
        if (it == tag2name.end()) return Tag;
        std::string localKey(it->second);
        tag2format_const_iterator iform = tag2format.find(Tag);
        if ((iform == tag2format.end()) && iform->second.length()) {
            localKey += "+" + iform->second;
        }
        unique = !!it->second.compare(localKey);
        if (!unique) return Tag;  // unlikely except in a race

        ++i;
        // Algorithm to convert hash to next tag
        if (i < 32) {
            Tag = (Hash >> i);
            // size_t is 32 bits, or upper word zero, rotate
            if ((sizeof(Hash) <= 4) || ((Hash & (uint64_t(-1LL) << 32)) == 0)) {
                Tag |= Hash << (32 - i);
            }
        } else {
            Tag = Hash + i - 31;
        }
    }
    return emptyTag;
}

static int openFile(const char* name, int mode, bool warning) {
    int fd = TEMP_FAILURE_RETRY(open(name, mode));
    if ((fd < 0) && warning) {
        android::prdebug("Failed open %s (%d)", name, errno);
    }
    return fd;
}

void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) {
    android::RWLock::AutoRLock readLock(rwlock);

    tag2total_const_iterator itot = tag2total.find(tag);
    if (itot == tag2total.end()) return;  // source is a static entry

    size_t lastTotal = itot->second;

    // Every 16K (half the smallest configurable pmsg buffer size) record
    static const size_t rate_to_pmsg = 16 * 1024;
    if (lastTotal && ((android::sizesTotal() - lastTotal) < rate_to_pmsg)) {
        return;
    }

    static int pmsg_fd = -1;
    if (pmsg_fd < 0) {
        pmsg_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
        // unlikely, but deal with partners with borken pmsg
        if (pmsg_fd < 0) return;
    }

    std::string Name = tag2name[tag];
    tag2format_const_iterator iform = tag2format.find(tag);
    std::string Format = (iform != tag2format.end()) ? iform->second : "";

    auto ctx = create_android_logger(TAG_DEF_LOG_TAG);
    auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
    if (android_log_write_int32(ctx, static_cast<int32_t>(tag) < 0) ||
        android_log_write_string8_len(ctx, Name.c_str(), Name.size()) < 0 ||
        android_log_write_string8_len(ctx, Format.c_str(), Format.size()) < 0) {
        return;
    }

    const char* cp = nullptr;
    ssize_t len = android_log_write_list_buffer(ctx, &cp);

    if (len <= 0 || cp == nullptr) {
        return;
    }

    std::string buffer(cp, len);

    /*
     *  struct {
     *      // what we provide to pstore
     *      android_pmsg_log_header_t pmsgHeader;
     *      // what we provide to file
     *      android_log_header_t header;
     *      // caller provides
     *      union {
     *          struct {
     *              char     prio;
     *              char     payload[];
     *          } string;
     *          struct {
     *              uint32_t tag
     *              char     payload[];
     *          } binary;
     *      };
     *  };
     */

    struct timespec ts;
    clock_gettime(android_log_clockid(), &ts);

    android_log_header_t header = {
        .id = LOG_ID_EVENTS,
        .tid = (uint16_t)gettid(),
        .realtime.tv_sec = (uint32_t)ts.tv_sec,
        .realtime.tv_nsec = (uint32_t)ts.tv_nsec,
    };

    uint32_t outTag = TAG_DEF_LOG_TAG;
    outTag = get4LE((const char*)&outTag);

    android_pmsg_log_header_t pmsgHeader = {
        .magic = LOGGER_MAGIC,
        .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) + sizeof(outTag) +
                          buffer.length()),
        .uid = (uint16_t)AID_ROOT,
        .pid = (uint16_t)getpid(),
    };

    struct iovec Vec[] = { { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) },
                           { (unsigned char*)&header, sizeof(header) },
                           { (unsigned char*)&outTag, sizeof(outTag) },
                           { (unsigned char*)const_cast<char*>(buffer.data()),
                             buffer.length() } };

    tag2uid_const_iterator ut = tag2uid.find(tag);
    if (ut == tag2uid.end()) {
        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
    } else if (uid != AID_ROOT) {
        pmsgHeader.uid = (uint16_t)uid;
        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
    } else {
        for (auto& it : ut->second) {
            pmsgHeader.uid = (uint16_t)it;
            TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
        }
    }
}

void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) {
    static const int mode =
        O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY;

    int fd = openFile(dynamic_event_log_tags, mode, true);
    if (fd < 0) return;

    android::RWLock::AutoWLock writeLock(rwlock);

    std::string ret = formatEntry_locked(tag, uid, false);
    android::base::WriteStringToFd(ret, fd);
    close(fd);

    size_t size = 0;
    file2watermark_const_iterator iwater;

    iwater = file2watermark.find(dynamic_event_log_tags);
    if (iwater != file2watermark.end()) size = iwater->second;

    file2watermark[dynamic_event_log_tags] = size + ret.length();
}

void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) {
    static const int mode =
        O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY;

    static bool one = true;
    int fd = openFile(debug_event_log_tags, mode, one);
    one = fd >= 0;
    if (!one) return;

    android::RWLock::AutoWLock writeLock(rwlock);

    std::string ret = formatEntry_locked(tag, uid, false);
    android::base::WriteStringToFd(ret, fd);
    close(fd);

    size_t size = 0;
    file2watermark_const_iterator iwater;

    iwater = file2watermark.find(debug_event_log_tags);
    if (iwater != file2watermark.end()) size = iwater->second;

    file2watermark[debug_event_log_tags] = size + ret.length();
}

// How we maintain some runtime or reboot stickiness
void LogTags::WritePersistEventLogTags(uint32_t tag, uid_t uid,
                                       const char* source) {
    // very unlikely
    bool etc = source && !strcmp(source, system_event_log_tags);
    if (etc) return;

    bool dynamic = source && !strcmp(source, dynamic_event_log_tags);
    bool debug = (!dynamic && source && !strcmp(source, debug_event_log_tags)) ||
                 !__android_log_is_debuggable();

    WritePmsgEventLogTags(tag, uid);

    size_t lastTotal = 0;
    {
        android::RWLock::AutoRLock readLock(rwlock);

        tag2total_const_iterator itot = tag2total.find(tag);
        if (itot != tag2total.end()) lastTotal = itot->second;
    }

    if (lastTotal == 0) {  // denotes first time for this one
        if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) {
            WriteDynamicEventLogTags(tag, uid);
        }

        if (!debug && !RebuildFileEventLogTags(debug_event_log_tags)) {
            WriteDebugEventLogTags(tag, uid);
        }
    }

    lastTotal = android::sizesTotal();
    if (!lastTotal) ++lastTotal;

    // record totals for next watermark.
    android::RWLock::AutoWLock writeLock(rwlock);
    tag2total[tag] = lastTotal;
}

// nameToTag converts a name into an event tag. If format is NULL, then we
// are in readonly mode.
uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) {
    std::string Name = std::string(name);
    bool write = format != nullptr;
    bool updateUid = uid != AID_ROOT;
    bool updateFormat = format && *format;
    bool unique;
    uint32_t Tag;

    {
        android::RWLock::AutoRLock readLock(rwlock);

        Tag = nameToTag_locked(Name, format, unique);
        if (updateUid && (Tag != emptyTag) && !unique) {
            tag2uid_const_iterator ut = tag2uid.find(Tag);
            if (updateUid) {
                if ((ut != tag2uid.end()) &&
                    (ut->second.find(uid) == ut->second.end())) {
                    unique = write;  // write passthrough to update uid counts
                    if (!write) Tag = emptyTag;  // deny read access
                }
            } else {
                unique = write && (ut != tag2uid.end());
            }
        }
    }

    if (Tag == emptyTag) return Tag;
    WritePmsgEventLogTags(Tag, uid);  // record references periodically
    if (!unique) return Tag;

    bool updateWrite = false;
    bool updateTag;

    // Special case of AddEventLogTags, checks per-uid counter which makes
    // no sense there, and is also optimized somewhat to reduce write times.
    {
        android::RWLock::AutoWLock writeLock(rwlock);

        // double check after switch from read lock to write lock for Tag
        updateTag = tag2name.find(Tag) == tag2name.end();
        // unlikely, either update, race inviting conflict or multiple uids
        if (!updateTag) {
            Tag = nameToTag_locked(Name, format, unique);
            if (Tag == emptyTag) return Tag;
            // is it multiple uid's setting this value
            if (!unique) {
                tag2uid_const_iterator ut = tag2uid.find(Tag);
                if (updateUid) {
                    // Add it to the uid list
                    if ((ut == tag2uid.end()) ||
                        (ut->second.find(uid) != ut->second.end())) {
                        return Tag;
                    }
                    const_cast<uid_list&>(ut->second).emplace(uid);
                    updateWrite = true;
                } else {
                    if (ut == tag2uid.end()) return Tag;
                    // (system) adding a global one, erase the uid list
                    tag2uid.erase(ut);
                    updateWrite = true;
                }
            }
        }

        // Update section
        size_t count;
        if (updateUid) {
            count = 0;
            uid2count_const_iterator ci = uid2count.find(uid);
            if (ci != uid2count.end()) {
                count = ci->second;
                if (count >= max_per_uid) {
                    if (!updateWrite) return emptyTag;
                    // If we are added to the per-Uid perms, leak the Tag
                    // if it already exists.
                    updateUid = false;
                    updateTag = false;
                    updateFormat = false;
                }
            }
        }

        // updateWrite -> trigger output on modified content, reset tag2total
        //    also sets static to dynamic entries if they are alterred,
        //    only occurs if they have a uid, and runtime adds another uid.
        if (updateWrite) tag2total[Tag] = 0;

        if (updateTag) {
            // mark as a dynamic entry, but do not upset current total counter
            tag2total_const_iterator itot = tag2total.find(Tag);
            if (itot == tag2total.end()) tag2total[Tag] = 0;

            if (*format) {
                key2tag[Name + "+" + format] = Tag;
                if (key2tag.find(Name) == key2tag.end()) key2tag[Name] = Tag;
            } else {
                key2tag[Name] = Tag;
            }
            tag2name[Tag] = Name;
        }
        if (updateFormat) tag2format[Tag] = format;

        if (updateUid) {
            tag2uid[Tag].emplace(uid);
            uid2count[uid] = count + 1;
        }
    }

    if (updateTag || updateFormat || updateWrite) {
        WritePersistEventLogTags(Tag, uid);
    }

    return Tag;
}

std::string LogTags::formatEntry(uint32_t tag, uid_t uid, const char* name,
                                 const char* format) {
    if (!format || !format[0]) {
        return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name);
    }
    size_t len = (strlen(name) + 7) / 8;
    static const char tabs[] = "\t\t\t";
    if (len > strlen(tabs)) len = strlen(tabs);
    std::string Uid;
    if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid);
    return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n", tag, name,
                                       &tabs[len], format, Uid.c_str());
}

std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid,
                                        bool authenticate) {
    const char* name = tag2name[tag].c_str();

    const char* format = "";
    tag2format_const_iterator iform = tag2format.find(tag);
    if (iform != tag2format.end()) format = iform->second.c_str();

    // Access permission test, do not report dynamic entries
    // that do not belong to us.
    tag2uid_const_iterator ut = tag2uid.find(tag);
    if (ut == tag2uid.end()) {
        return formatEntry(tag, AID_ROOT, name, format);
    }
    if (uid != AID_ROOT) {
        if (authenticate && (ut->second.find(uid) == ut->second.end())) {
            return std::string("");
        }
        return formatEntry(tag, uid, name, format);
    }

    // Show all, one for each registered uid (we are group root)
    std::string ret;
    for (auto& it : ut->second) {
        ret += formatEntry(tag, it, name, format);
    }
    return ret;
}

std::string LogTags::formatEntry(uint32_t tag, uid_t uid) {
    android::RWLock::AutoRLock readLock(rwlock);
    return formatEntry_locked(tag, uid);
}

std::string LogTags::formatGetEventTag(uid_t uid, const char* name,
                                       const char* format) {
    bool all = name && (name[0] == '*') && !name[1];
    bool list = !name || all;
    std::string ret;

    if (!list) {
        // switch to read entry only if format == "*"
        if (format && (format[0] == '*') && !format[1]) format = nullptr;

        // WAI: for null format, only works for a single entry, we can have
        // multiple entries, one for each format, so we find first entry
        // recorded, or entry with no format associated with it.
        // We may desire to print all that match the name, but we did not
        // add a mapping table for that and the cost is too high.
        uint32_t tag = nameToTag(uid, name, format);
        if (tag == emptyTag) return std::string("-1 ESRCH");
        if (uid == AID_ROOT) {
            android::RWLock::AutoRLock readLock(rwlock);

            // first uid in list so as to manufacture an accurate reference
            tag2uid_const_iterator ut = tag2uid.find(tag);
            if ((ut != tag2uid.end()) &&
                (ut->second.begin() != ut->second.end())) {
                uid = *(ut->second.begin());
            }
        }
        ret = formatEntry(tag, uid, name, format ?: tagToFormat(tag));
        if (!ret.length()) return std::string("-1 ESRCH");
        return ret;
    }

    android::RWLock::AutoRLock readLock(rwlock);
    if (all) {
        // everything under the sun
        for (const auto& it : tag2name) {
            ret += formatEntry_locked(it.first, uid);
        }
    } else {
        // set entries are dynamic
        for (const auto& it : tag2total) {
            ret += formatEntry_locked(it.first, uid);
        }
    }
    return ret;
}
