/*
 * Copyright (C) 2016 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.
 */

#ifndef ANDROID_MEDIA_MEDIAMETRICSITEM_H
#define ANDROID_MEDIA_MEDIAMETRICSITEM_H

#include "MediaMetrics.h"
#include "MediaMetricsConstants.h"

#include <algorithm>
#include <map>
#include <string>
#include <sys/types.h>
#include <variant>

#include <binder/Parcel.h>
#include <log/log.h>
#include <utils/Errors.h>
#include <utils/Timers.h> // nsecs_t

namespace android {

namespace media { class IMediaMetricsService; }

class Parcel;

/*
 * MediaMetrics Item
 *
 * The MediaMetrics Item allows get/set operations and recording to the service.
 *
 * The MediaMetrics LogItem is a faster logging variant. It allows set operations only,
 * and then recording to the service.
 *
 * The Byte String format is as follows:
 *
 * For Java
 *  int64 corresponds to long
 *  int32, uint32 corresponds to int
 *  uint16 corresponds to char
 *  uint8, int8 corresponds to byte
 *
 * For items transmitted from Java, uint8 and uint32 values are limited
 * to INT8_MAX and INT32_MAX.  This constrains the size of large items
 * to 2GB, which is consistent with ByteBuffer max size. A native item
 * can conceivably have size of 4GB.
 *
 * Physical layout of integers and doubles within the MediaMetrics byte string
 * is in Native / host order, which is usually little endian.
 *
 * Note that primitive data (ints, doubles) within a Byte String has
 * no extra padding or alignment requirements, like ByteBuffer.
 *
 * -- begin of item
 * -- begin of header
 * (uint32) item size: including the item size field
 * (uint32) header size, including the item size and header size fields.
 * (uint16) version: exactly 0
 * (uint16) key size, that is key strlen + 1 for zero termination.
 * (int8)+ key, a string which is 0 terminated (UTF-8).
 * (int32) pid
 * (int32) uid
 * (int64) timestamp
 * -- end of header
 * -- begin body
 * (uint32) number of properties
 * -- repeat for number of properties
 *     (uint16) property size, including property size field itself
 *     (uint8) type of property
 *     (int8)+ key string, including 0 termination
 *      based on type of property (given above), one of:
 *       (int32)
 *       (int64)
 *       (double)
 *       (int8)+ for TYPE_CSTRING, including 0 termination
 *       (int64, int64) for rate
 * -- end body
 * -- end of item
 *
 * The Byte String format must match MediaMetrics.java.
 */

namespace mediametrics {

// Type must match MediaMetrics.java
enum Type {
    kTypeNone = 0,
    kTypeInt32 = 1,
    kTypeInt64 = 2,
    kTypeDouble = 3,
    kTypeCString = 4,
    kTypeRate = 5,
};

/*
 * Time printing
 *
 * kPrintFormatLong time string is 19 characters (including null termination).
 * Example Long Form: "03-27 16:47:06.187"
 *                     MM DD HH MM SS MS
 *
 * kPrintFormatShort time string is 13 characters (including null termination).
 * Example Short Form: "16:47:06.187"
 *                      HH MM SS MS
 */

enum PrintFormat {
    kPrintFormatLong = 0,
    kPrintFormatShort = 1,
};

/**
 * Converts real time in ns to a time string object, with format similar to logcat.
 *
 * \param ns         input real time in nanoseconds to convert.
 * \param buffer     the buffer location to put the converted string.
 * \param bufferSize the size of buffer in bytes.
 * \param format     format, from enum PrintFormat.
 */
void nsToString(
        int64_t ns, char *buffer, size_t bufferSize, PrintFormat format = kPrintFormatLong);

// Contains the time string
struct time_string_t {
    char time[19]; /* minimum size buffer */
};

/**
 * Converts real time in ns to a time string object, with format similar to logcat.
 *
 * \param ns     input real time in nanoseconds to convert.
 * \param format format, from enum PrintFormat.
 * \return       a time_string_t object with the time string encoded.
 */
static inline time_string_t timeStringFromNs(int64_t ns, PrintFormat format = kPrintFormatLong) {
    time_string_t ts;
    nsToString(ns, ts.time, sizeof(ts.time), format);
    return ts;
}

/**
 * Finds the end of the common time prefix.
 *
 * This is as an option to remove the common time prefix to avoid
 * unnecessary duplicated strings.
 *
 * \param time1 a time string from timeStringFromNs
 * \param time2 a time string from timeStringFromNs
 * \return      the position where the common time prefix ends. For abbreviated
 *              printing of time2, offset the character pointer by this position.
 */
static inline size_t commonTimePrefixPosition(const char *time1, const char *time2) {
    size_t i;

    // Find location of the first mismatch between strings
    for (i = 0; ; ++i) {
        if (time1[i] != time2[i]) {
            break;
        }
        if (time1[i] == 0) {
            return i; // strings match completely
        }
    }

    // Go backwards until we find a delimeter or space.
    for (; i > 0
           && isdigit(time1[i]) // still a number
           && time1[i - 1] != ' '
         ; --i) {
    }
    return i;
}

/**
 * The MediaMetrics Item has special Item properties,
 * derived internally or through dedicated setters.
 *
 * For consistency we use the following keys to represent
 * these special Item properties when in a generic Bundle
 * or in a std::map.
 *
 * These values must match MediaMetrics.java
 */
static inline constexpr const char *BUNDLE_TOTAL_SIZE = "_totalSize";
static inline constexpr const char *BUNDLE_HEADER_SIZE = "_headerSize";
static inline constexpr const char *BUNDLE_VERSION = "_version";
static inline constexpr const char *BUNDLE_KEY_SIZE = "_keySize";
static inline constexpr const char *BUNDLE_KEY = "_key";
static inline constexpr const char *BUNDLE_PID = "_pid";
static inline constexpr const char *BUNDLE_UID = "_uid";
static inline constexpr const char *BUNDLE_TIMESTAMP = "_timestamp";
static inline constexpr const char *BUNDLE_PROPERTY_COUNT = "_propertyCount";

template<size_t N>
static inline bool startsWith(const std::string &s, const char (&comp)[N]) {
    return !strncmp(s.c_str(), comp, N - 1); // last char is null termination
}

static inline bool startsWith(const std::string& s, const std::string& comp) {
    return !strncmp(s.c_str(), comp.c_str(), comp.size());
}

/**
 * Defers a function to run in the destructor.
 *
 * This helper class is used to log results on exit of a method.
 */
class Defer {
public:
    template <typename U>
    explicit Defer(U &&f) : mThunk(std::forward<U>(f)) {}
    ~Defer() { mThunk(); }

private:
    const std::function<void()> mThunk;
};

/**
 * Media Metrics BaseItem
 *
 * A base class which contains utility static functions to write to a byte stream
 * and access the Media Metrics service.
 */

class BaseItem {
    friend class MediaMetricsDeathNotifier; // for dropInstance
    // enabled 1, disabled 0
public:
    // are we collecting metrics data
    static bool isEnabled();
    // returns the MediaMetrics service if active.
    static sp<media::IMediaMetricsService> getService();
    // submits a raw buffer directly to the MediaMetrics service - this is highly optimized.
    static status_t submitBuffer(const char *buffer, size_t len);

protected:
    static constexpr const char * const EnabledProperty = "media.metrics.enabled";
    static constexpr const char * const EnabledPropertyPersist = "persist.media.metrics.enabled";
    static const int EnabledProperty_default = 1;

    // let's reuse a binder connection
    static sp<media::IMediaMetricsService> sMediaMetricsService;

    static void dropInstance();

    template <typename T>
    struct is_item_type {
        static constexpr inline bool value =
             std::is_same<T, int32_t>::value
             || std::is_same<T, int64_t>::value
             || std::is_same<T, double>::value
             || std::is_same<T, std::pair<int64_t, int64_t>>:: value
             || std::is_same<T, std::string>::value
             || std::is_same<T, std::monostate>::value;
    };

    template <typename T>
    struct get_type_of {
        static_assert(is_item_type<T>::value);
        static constexpr inline Type value =
             std::is_same<T, int32_t>::value ? kTypeInt32
             : std::is_same<T, int64_t>::value ? kTypeInt64
             : std::is_same<T, double>::value ? kTypeDouble
             : std::is_same<T, std::pair<int64_t, int64_t>>:: value ? kTypeRate
             : std::is_same<T, std::string>::value ? kTypeCString
             : std::is_same<T, std::monostate>::value ? kTypeNone
         : kTypeNone;
    };

    template <typename T>
    static size_t sizeOfByteString(const char *name, const T& value) {
        static_assert(is_item_type<T>::value);
        return 2 + 1 + strlen(name) + 1 + sizeof(value);
    }
    template <> // static
    size_t sizeOfByteString(const char *name, const std::string& value) {
        return 2 + 1 + strlen(name) + 1 + value.size() + 1;
    }
    template <> // static
    size_t sizeOfByteString(const char *name, const std::monostate&) {
         return 2 + 1 + strlen(name) + 1;
    }
    // for speed
    static size_t sizeOfByteString(const char *name, const char *value) {
        return 2 + 1 + strlen(name) + 1 + strlen(value) + 1;
    }

    template <typename T>
    static status_t insert(const T& val, char **bufferpptr, char *bufferptrmax) {
        static_assert(std::is_trivially_constructible<T>::value);
        const size_t size = sizeof(val);
        if (*bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(*bufferpptr, &val, size);
        *bufferpptr += size;
        return NO_ERROR;
    }
    template <> // static
    status_t insert(const std::string& val, char **bufferpptr, char *bufferptrmax) {
        const size_t size = val.size() + 1;
        if (size > UINT16_MAX || *bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(*bufferpptr, val.c_str(), size);
        *bufferpptr += size;
        return NO_ERROR;
    }
    template <> // static
    status_t insert(const std::pair<int64_t, int64_t>& val,
            char **bufferpptr, char *bufferptrmax) {
        const size_t size = sizeof(val.first) + sizeof(val.second);
        if (*bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(*bufferpptr, &val.first, sizeof(val.first));
        memcpy(*bufferpptr + sizeof(val.first), &val.second, sizeof(val.second));
        *bufferpptr += size;
        return NO_ERROR;
    }
    template <> // static
    status_t insert(const std::monostate&, char **, char *) {
        return NO_ERROR;
    }
    // for speed
    static status_t insert(const char *val, char **bufferpptr, char *bufferptrmax) {
        const size_t size = strlen(val) + 1;
        if (size > UINT16_MAX || *bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(*bufferpptr, val, size);
        *bufferpptr += size;
        return NO_ERROR;
    }

    template <typename T>
    static status_t writeToByteString(
            const char *name, const T& value, char **bufferpptr, char *bufferptrmax) {
        static_assert(is_item_type<T>::value);
        const size_t len = sizeOfByteString(name, value);
        if (len > UINT16_MAX) return BAD_VALUE;
        return insert((uint16_t)len, bufferpptr, bufferptrmax)
                ?: insert((uint8_t)get_type_of<T>::value, bufferpptr, bufferptrmax)
                ?: insert(name, bufferpptr, bufferptrmax)
                ?: insert(value, bufferpptr, bufferptrmax);
    }
    // for speed
    static status_t writeToByteString(
            const char *name, const char *value, char **bufferpptr, char *bufferptrmax) {
        const size_t len = sizeOfByteString(name, value);
        if (len > UINT16_MAX) return BAD_VALUE;
        return insert((uint16_t)len, bufferpptr, bufferptrmax)
                ?: insert((uint8_t)kTypeCString, bufferpptr, bufferptrmax)
                ?: insert(name, bufferpptr, bufferptrmax)
                ?: insert(value, bufferpptr, bufferptrmax);
    }

    template <typename T>
    static void toStringBuffer(
            const char *name, const T& value, char *buffer, size_t length) = delete;
    template <> // static
    void toStringBuffer(
            const char *name, const int32_t& value, char *buffer, size_t length) {
        snprintf(buffer, length, "%s=%d", name, value);
    }
    template <> // static
    void toStringBuffer(
            const char *name, const int64_t& value, char *buffer, size_t length) {
        snprintf(buffer, length, "%s=%lld", name, (long long)value);
    }
    template <> // static
    void toStringBuffer(
            const char *name, const double& value, char *buffer, size_t length) {
        snprintf(buffer, length, "%s=%e", name, value);
    }
    template <> // static
    void toStringBuffer(
            const char *name, const std::pair<int64_t, int64_t>& value,
            char *buffer, size_t length) {
        snprintf(buffer, length, "%s=%lld/%lld",
                name, (long long)value.first, (long long)value.second);
    }
    template <> // static
    void toStringBuffer(
            const char *name, const std::string& value, char *buffer, size_t length) {
        // TODO sanitize string for ':' '='
        snprintf(buffer, length, "%s=%s", name, value.c_str());
    }
    template <> // static
    void toStringBuffer(
            const char *name, const std::monostate&, char *buffer, size_t length) {
        snprintf(buffer, length, "%s=()", name);
    }

    template <typename T>
    static status_t writeToParcel(
            const char *name, const T& value, Parcel *parcel) = delete;
    template <> // static
    status_t writeToParcel(
            const char *name, const int32_t& value, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of<int32_t>::value)
               ?: parcel->writeInt32(value);
    }
    template <> // static
    status_t writeToParcel(
            const char *name, const int64_t& value, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of<int64_t>::value)
               ?: parcel->writeInt64(value);
    }
    template <> // static
    status_t writeToParcel(
            const char *name, const double& value, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of<double>::value)
               ?: parcel->writeDouble(value);
    }
    template <> // static
    status_t writeToParcel(
            const char *name, const std::pair<int64_t, int64_t>& value, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of< std::pair<int64_t, int64_t>>::value)
               ?: parcel->writeInt64(value.first)
               ?: parcel->writeInt64(value.second);
    }
    template <> // static
    status_t writeToParcel(
            const char *name, const std::string& value, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of<std::string>::value)
               ?: parcel->writeCString(value.c_str());
    }
    template <> // static
    status_t writeToParcel(
            const char *name, const std::monostate&, Parcel *parcel) {
        return parcel->writeCString(name)
               ?: parcel->writeInt32(get_type_of<std::monostate>::value);
    }

    template <typename T>
    static status_t extract(T *val, const char **bufferpptr, const char *bufferptrmax) {
        static_assert(std::is_trivially_constructible<T>::value);
        const size_t size = sizeof(*val);
        if (*bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(val, *bufferpptr, size);
        *bufferpptr += size;
        return NO_ERROR;
    }
    template <> // static
    status_t extract(std::string *val, const char **bufferpptr, const char *bufferptrmax) {
        const char *ptr = *bufferpptr;
        do {
            if (ptr >= bufferptrmax) {
                ALOGE("%s: buffer exceeded", __func__);
                android_errorWriteLog(0x534e4554, "204445255");
                return BAD_VALUE;
            }
        } while (*ptr++ != 0);
        // ptr is terminator+1, == bufferptrmax if we finished entire buffer
        *val = *bufferpptr;
        *bufferpptr = ptr;
        return NO_ERROR;
    }
    template <> // static
    status_t extract(std::pair<int64_t, int64_t> *val,
            const char **bufferpptr, const char *bufferptrmax) {
        const size_t size = sizeof(val->first) + sizeof(val->second);
        if (*bufferpptr + size > bufferptrmax) {
            ALOGE("%s: buffer exceeded with size %zu", __func__, size);
            return BAD_VALUE;
        }
        memcpy(&val->first, *bufferpptr, sizeof(val->first));
        memcpy(&val->second, *bufferpptr + sizeof(val->first), sizeof(val->second));
        *bufferpptr += size;
        return NO_ERROR;
    }
    template <> // static
    status_t extract(std::monostate *, const char **, const char *) {
        return NO_ERROR;
    }
};

/**
 * Media Metrics BufferedItem
 *
 * A base class which represents a put-only Media Metrics item, storing
 * the Media Metrics data in a buffer with begin and end pointers.
 *
 * If a property key is entered twice, it will be stored in the buffer twice,
 * and (implementation defined) the last value for that key will be used
 * by the Media Metrics service.
 *
 * For realloc, a baseRealloc pointer must be passed in either explicitly
 * or implicitly in the constructor. This will be updated with the value used on realloc.
 */
class BufferedItem : public BaseItem {
public:
    static inline constexpr uint16_t kVersion = 0;

    virtual ~BufferedItem() = default;
    BufferedItem(const BufferedItem&) = delete;
    BufferedItem& operator=(const BufferedItem&) = delete;

    BufferedItem(const std::string& key, char *begin, char *end)
        : BufferedItem(key.c_str(), begin, end) { }

    BufferedItem(const char *key, char *begin, char *end)
        : BufferedItem(key, begin, end, nullptr) { }

    BufferedItem(const char *key, char **begin, char *end)
        : BufferedItem(key, *begin, end, begin) { }

    BufferedItem(const char *key, char *begin, char *end, char **baseRealloc)
        : mBegin(begin)
        , mEnd(end)
        , mBaseRealloc(baseRealloc)
    {
        init(key);
    }

    template<typename T>
    BufferedItem &set(const char *key, const T& value) {
        reallocFor(sizeOfByteString(key, value));
        if (mStatus == NO_ERROR) {
            mStatus = BaseItem::writeToByteString(key, value, &mBptr, mEnd);
            ++mPropCount;
        }
        return *this;
    }

    template<typename T>
    BufferedItem &set(const std::string& key, const T& value) {
        return set(key.c_str(), value);
    }

    BufferedItem &setPid(pid_t pid) {
        if (mStatus == NO_ERROR) {
            copyTo(mBegin + mHeaderLen - 16, (int32_t)pid);
        }
        return *this;
    }

    BufferedItem &setUid(uid_t uid) {
        if (mStatus == NO_ERROR) {
            copyTo(mBegin + mHeaderLen - 12, (int32_t)uid);
        }
        return *this;
    }

    BufferedItem &setTimestamp(nsecs_t timestamp) {
        if (mStatus == NO_ERROR) {
            copyTo(mBegin + mHeaderLen - 8, (int64_t)timestamp);
        }
        return *this;
    }

    bool record() {
        return updateHeader()
                && BaseItem::submitBuffer(getBuffer(), getLength()) == OK;
    }

    bool isValid () const {
        return mStatus == NO_ERROR;
    }

    char *getBuffer() const { return mBegin; }
    size_t getLength() const { return mBptr - mBegin; }
    size_t getRemaining() const { return mEnd - mBptr; }
    size_t getCapacity() const { return mEnd - mBegin; }

    bool updateHeader() {
        if (mStatus != NO_ERROR) return false;
        copyTo(mBegin + 0, (uint32_t)getLength());
        copyTo(mBegin + 4, (uint32_t)mHeaderLen);
        copyTo(mBegin + mHeaderLen, (uint32_t)mPropCount);
        return true;
    }

protected:
    BufferedItem() = default;

    void reallocFor(size_t required) {
        if (mStatus != NO_ERROR) return;
        const size_t remaining = getRemaining();
        if (required <= remaining) return;
        if (mBaseRealloc == nullptr) {
            mStatus = NO_MEMORY;
            return;
        }

        const size_t current = getLength();
        size_t minimum = current + required;
        if (minimum > SSIZE_MAX >> 1) {
            mStatus = NO_MEMORY;
            return;
        }
        minimum <<= 1;
        void *newptr = realloc(*mBaseRealloc, minimum);
        if (newptr == nullptr) {
            mStatus = NO_MEMORY;
            return;
        }
        if (newptr != *mBaseRealloc) {
            // ALOGD("base changed! current:%zu new size %zu", current, minimum);
            if (*mBaseRealloc == nullptr) {
                memcpy(newptr, mBegin, current);
            }
            mBegin = (char *)newptr;
            *mBaseRealloc = mBegin;
            mEnd = mBegin + minimum;
            mBptr = mBegin + current;
        } else {
            // ALOGD("base kept! current:%zu new size %zu", current, minimum);
            mEnd = mBegin + minimum;
        }
    }
    template<typename T>
    void copyTo(char *ptr, const T& value) {
        memcpy(ptr, &value, sizeof(value));
    }

    void init(const char *key) {
        mBptr = mBegin;
        const size_t keylen = key == nullptr ? 0 : strlen(key) + 1;
        if (keylen <= 1) {
            mStatus = BAD_VALUE; // prevent null pointer or empty keys.
            return;
        }
        mHeaderLen = 4 + 4 + 2 + 2 + keylen + 4 + 4 + 8;
        reallocFor(mHeaderLen);
        if (mStatus != NO_ERROR) return;
        mBptr = mBegin + mHeaderLen + 4; // this includes propcount.

        if (mEnd < mBptr || keylen > UINT16_MAX) {
           mStatus = NO_MEMORY;
           mBptr = mEnd;
           return;
        }
        copyTo(mBegin + 8, kVersion);
        copyTo(mBegin + 10, (uint16_t)keylen);
        strcpy(mBegin + 12, key);

        // initialize some parameters (that could be overridden)
        setPid(-1);
        setUid(-1);
        setTimestamp(0);
    }

    char *mBegin = nullptr;
    char *mEnd = nullptr;
    char **mBaseRealloc = nullptr;  // set to an address if realloc should be done.
                                    // upon return, that pointer is updated with
                                    // whatever needs to be freed.
    char *mBptr = nullptr;
    status_t mStatus = NO_ERROR;
    uint32_t mPropCount = 0;
    uint32_t mHeaderLen = 0;
};

/**
 * MediaMetrics LogItem is a stack allocated mediametrics item used for
 * fast logging.  It falls over to a malloc if needed.
 *
 * This is templated with a buffer size to allocate on the stack.
 */
template <size_t N = 4096>
class LogItem : public BufferedItem {
public:
    explicit LogItem(const std::string& key) : LogItem(key.c_str()) { }

    // Since this class will not be defined before the base class, we initialize variables
    // in our own order.
    explicit LogItem(const char *key) {
         mBegin = mBuffer;
         mEnd = mBuffer + N;
         mBaseRealloc = &mReallocPtr;
         init(key);
    }

    ~LogItem() override {
        if (mReallocPtr != nullptr) { // do the check before calling free to avoid overhead.
            free(mReallocPtr);
        }
    }

private:
    char *mReallocPtr = nullptr;  // set non-null by base class if realloc happened.
    char mBuffer[N];
};


/**
 * Media Metrics Item
 *
 * A mutable item representing an event or record that will be
 * logged with the Media Metrics service.  For client logging, one should
 * use the mediametrics::Item.
 *
 * The Item is designed for the service as it has getters.
 */
class Item final : public mediametrics::BaseItem {
public:

    class Prop {
    public:
        using Elem = std::variant<
                std::monostate,               // kTypeNone
                int32_t,                      // kTypeInt32
                int64_t,                      // kTypeInt64
                double,                       // kTypeDouble
                std::string,                  // kTypeCString
                std::pair<int64_t, int64_t>   // kTypeRate
                >;

        Prop() = default;
        Prop(const Prop& other) {
           *this = other;
        }
        Prop& operator=(const Prop& other) {
            mName = other.mName;
            mElem = other.mElem;
            return *this;
        }
        Prop(Prop&& other) noexcept {
            *this = std::move(other);
        }
        Prop& operator=(Prop&& other) noexcept {
            mName = std::move(other.mName);
            mElem = std::move(other.mElem);
            return *this;
        }

        bool operator==(const Prop& other) const {
            return mName == other.mName && mElem == other.mElem;
        }
        bool operator!=(const Prop& other) const {
            return !(*this == other);
        }

        void clear() {
            mName.clear();
            mElem = std::monostate{};
        }
        void clearValue() {
            mElem = std::monostate{};
        }

        const char *getName() const {
            return mName.c_str();
        }

        void swap(Prop& other) {
            std::swap(mName, other.mName);
            std::swap(mElem, other.mElem);
        }

        void setName(const char *name) {
            mName = name;
        }

        bool isNamed(const char *name) const {
            return mName == name;
        }

        template <typename T> void visit(T f) const {
            std::visit(f, mElem);
        }

        template <typename T> bool get(T *value) const {
            auto pval = std::get_if<T>(&mElem);
            if (pval != nullptr) {
                *value = *pval;
                return true;
            }
            return false;
        }

        const Elem& get() const {
            return mElem;
        }

        template <typename T> void set(const T& value) {
            mElem = value;
        }

        template <typename T> void add(const T& value) {
            auto pval = std::get_if<T>(&mElem);
            if (pval != nullptr) {
                *pval += value;
            } else {
                mElem = value;
            }
        }

        template <> void add(const std::pair<int64_t, int64_t>& value) {
            auto pval = std::get_if<std::pair<int64_t, int64_t>>(&mElem);
            if (pval != nullptr) {
                pval->first += value.first;
                pval->second += value.second;
            } else {
                mElem = value;
            }
        }

        status_t writeToParcel(Parcel *parcel) const {
            return std::visit([this, parcel](auto &value) {
                    return BaseItem::writeToParcel(mName.c_str(), value, parcel);}, mElem);
        }

        void toStringBuffer(char *buffer, size_t length) const {
            return std::visit([this, buffer, length](auto &value) {
                BaseItem::toStringBuffer(mName.c_str(), value, buffer, length);}, mElem);
        }

        size_t getByteStringSize() const {
            return std::visit([this](auto &value) {
                return BaseItem::sizeOfByteString(mName.c_str(), value);}, mElem);
        }

        status_t writeToByteString(char **bufferpptr, char *bufferptrmax) const {
            return std::visit([this, bufferpptr, bufferptrmax](auto &value) {
                return BaseItem::writeToByteString(mName.c_str(), value, bufferpptr, bufferptrmax);
            }, mElem);
        }

        status_t readFromParcel(const Parcel& data);

        status_t readFromByteString(const char **bufferpptr, const char *bufferptrmax);

    private:
        std::string mName;
        Elem mElem;
    };

    // Iteration of props within item
    class iterator {
    public:
        explicit iterator(const std::map<std::string, Prop>::const_iterator &_it) : it(_it) { }
        iterator &operator++() {
            ++it;
            return *this;
        }
        bool operator!=(iterator &other) const {
            return it != other.it;
        }
        const Prop &operator*() const {
            return it->second;
        }

    private:
        std::map<std::string, Prop>::const_iterator it;
    };

    iterator begin() const {
        return iterator(mProps.cbegin());
    }

    iterator end() const {
        return iterator(mProps.cend());
    }

    // T must be convertible to mKey
    template <typename T>
    explicit Item(T key)
        : mKey(key) { }
    Item() = default;

    // We enable default copy and move constructors and make this class final
    // to prevent a derived class; this avoids possible data slicing.
    Item(const Item& other) = default;
    Item(Item&& other) = default;
    Item& operator=(const Item& other) = default;
    Item& operator=(Item&& other) = default;

    bool operator==(const Item& other) const {
        return mPid == other.mPid
            && mUid == other.mUid
            && mPkgName == other.mPkgName
            && mPkgVersionCode == other.mPkgVersionCode
            && mKey == other.mKey
            && mTimestamp == other.mTimestamp
            && mProps == other.mProps
            ;
    }
    bool operator!=(const Item& other) const {
        return !(*this == other);
    }

    template <typename T>
    static Item* create(T key) {
        return new Item(key);
    }
    static Item* create() {
        return new Item();
    }

        static Item* convert(mediametrics_handle_t);
        static mediametrics_handle_t convert(Item *);

        // access functions for the class
        ~Item();

    void clear() {
        mPid = -1;
        mUid = -1;
        mPkgName.clear();
        mPkgVersionCode = 0;
        mTimestamp = 0;
        mKey.clear();
        mProps.clear();
    }

    Item *dup() const { return new Item(*this); }

    Item &setKey(const char *key) {
        mKey = key;
        return *this;
    }
    const std::string& getKey() const { return mKey; }

    // # of properties in the record
    size_t count() const { return mProps.size(); }

    template<typename S, typename T>
    Item &set(S key, T value) {
        findOrAllocateProp(key).set(value);
        return *this;
    }

    // set values appropriately
    Item &setInt32(const char *key, int32_t value) {
        return set(key, value);
    }
    Item &setInt64(const char *key, int64_t value) {
        return set(key, value);
    }
    Item &setDouble(const char *key, double value) {
        return set(key, value);
    }
    Item &setRate(const char *key, int64_t count, int64_t duration) {
        return set(key, std::make_pair(count, duration));
    }
    Item &setCString(const char *key, const char *value) {
        return set(key, value);
    }

    // fused get/add/set; if attr wasn't there, it's a simple set.
    // type-mismatch counts as "wasn't there".
    template<typename S, typename T>
    Item &add(S key, T value) {
        findOrAllocateProp(key).add(value);
        return *this;
    }

    Item &addInt32(const char *key, int32_t value) {
        return add(key, value);
    }
    Item &addInt64(const char *key, int64_t value) {
        return add(key, value);
    }
    Item &addDouble(const char *key, double value) {
        return add(key, value);
    }
    Item &addRate(const char *key, int64_t count, int64_t duration) {
        return add(key, std::make_pair(count, duration));
    }

    // find & extract values
    // return indicates whether attr exists (and thus value filled in)
    // NULL parameter value suppresses storage of value.
    template<typename S, typename T>
    bool get(S key, T *value) const {
        const Prop *prop = findProp(key);
        return prop != nullptr && prop->get(value);
    }

    bool getInt32(const char *key, int32_t *value) const {
        return get(key, value);
    }
    bool getInt64(const char *key, int64_t *value) const {
        return get(key, value);
    }
    bool getDouble(const char *key, double *value) const {
        return get(key, value);
    }
    bool getRate(const char *key, int64_t *count, int64_t *duration, double *rate) const {
        std::pair<int64_t, int64_t> value;
        if (!get(key, &value)) return false;
        if (count != nullptr) *count = value.first;
        if (duration != nullptr) *duration = value.second;
        if (rate != nullptr) {
            if (value.second != 0) {
                *rate = (double)value.first / value.second;  // TODO: isn't INF OK?
            } else {
                *rate = 0.;
            }
        }
        return true;
    }
    // Caller owns the returned string
    bool getCString(const char *key, char **value) const {
        std::string s;
        if (get(key, &s)) {
            *value = strdup(s.c_str());
            return true;
        }
        return false;
    }
    bool getString(const char *key, std::string *value) const {
        return get(key, value);
    }

    const Prop::Elem* get(const char *key) const {
        const Prop *prop = findProp(key);
        return prop == nullptr ? nullptr : &prop->get();
    }

        // Deliver the item to MediaMetrics
        bool selfrecord();

    // remove indicated attributes and their values
    // filterNot() could also be called keepOnly()
    // return value is # attributes removed
    // XXX: perhaps 'remove' instead of 'filter'
    // XXX: filterNot would become 'keep'
    size_t filter(size_t count, const char *attrs[]);
    size_t filterNot(size_t count, const char *attrs[]);
    size_t filter(const char *attr) { return filter(1, &attr); }

        // below here are used on server side or to talk to server
        // clients need not worry about these.

        // timestamp, pid, and uid only used on server side
        // timestamp is in 'nanoseconds, unix time'
        Item &setTimestamp(nsecs_t);
        nsecs_t getTimestamp() const;

        Item &setPid(pid_t);
        pid_t getPid() const;

        Item &setUid(uid_t);
        uid_t getUid() const;

        Item &setPkgName(const std::string &pkgName);
        std::string getPkgName() const { return mPkgName; }

        Item &setPkgVersionCode(int64_t);
        int64_t getPkgVersionCode() const;

    // our serialization code for binder calls
    status_t writeToParcel(Parcel *) const;
    status_t readFromParcel(const Parcel&);

    status_t writeToByteString(char **bufferptr, size_t *length) const;
    status_t readFromByteString(const char *bufferptr, size_t length);


        std::string toString() const;
        const char *toCString();

    /**
     * Returns true if the item has a property with a target value.
     *
     * If propName is nullptr, hasPropElem() returns false.
     *
     * \param propName is the property name.
     * \param elem is the value to match.  std::monostate matches any.
     */
    bool hasPropElem(const char *propName, const Prop::Elem& elem) const {
        if (propName == nullptr) return false;
        const Prop::Elem *e = get(propName);
        return e != nullptr && (std::holds_alternative<std::monostate>(elem) || elem == *e);
    }

    /**
     * Returns -2, -1, 0 (success) if the item has a property (wildcard matched) with a
     * target value.
     *
     * The enum RecursiveWildcardCheck designates the meaning of the returned value.
     *
     * RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD = -2,
     * RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND = -1,
     * RECURSIVE_WILDCARD_CHECK_MATCH_FOUND = 0.
     *
     * If url is nullptr, RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD is returned.
     *
     * \param url is the full item + property name, which may have wildcards '*'
     *            denoting an arbitrary sequence of 0 or more characters.
     * \param elem is the target property value to match. std::monostate matches any.
     * \return 0 if the property was matched,
     *         -1 if the property was not matched and a wildcard char was encountered,
     *         -2 if the property was not matched with no wildcard char encountered.
     */
    enum RecursiveWildcardCheck {
        RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD = -2,
        RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND = -1,
        RECURSIVE_WILDCARD_CHECK_MATCH_FOUND = 0,
    };

    enum RecursiveWildcardCheck recursiveWildcardCheckElem(
        const char *url, const Prop::Elem& elem) const {
        if (url == nullptr) return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
        return recursiveWildcardCheckElem(getKey().c_str(), url, elem);
    }

private:

    enum RecursiveWildcardCheck recursiveWildcardCheckElem(
            const char *itemKeyPtr, const char *url, const Prop::Elem& elem) const {
        for (; *url && *itemKeyPtr; ++url, ++itemKeyPtr) {
            if (*url != *itemKeyPtr) {
                if (*url == '*') { // wildcard
                    ++url;
                    while (true) {
                        if (recursiveWildcardCheckElem(itemKeyPtr, url, elem)
                                == RECURSIVE_WILDCARD_CHECK_MATCH_FOUND) {
                            return RECURSIVE_WILDCARD_CHECK_MATCH_FOUND;
                        }
                        if (*itemKeyPtr == 0) break;
                        ++itemKeyPtr;
                    }
                    return RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND;
                }
                return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
            }
        }
        if (itemKeyPtr[0] != 0 || url[0] != '.') {
            return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
        }
        const char *propName = url + 1; // skip the '.'
        return hasPropElem(propName, elem)
                ? RECURSIVE_WILDCARD_CHECK_MATCH_FOUND
                : RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
    }

    // handle Parcel version 0
    int32_t writeToParcel0(Parcel *) const;
    int32_t readFromParcel0(const Parcel&);

    const Prop *findProp(const char *key) const {
        auto it = mProps.find(key);
        return it != mProps.end() ? &it->second : nullptr;
    }

    Prop &findOrAllocateProp(const char *key) {
        auto it = mProps.find(key);
        if (it != mProps.end()) return it->second;
        Prop &prop = mProps[key];
        prop.setName(key);
        return prop;
    }

    // Changes to member variables below require changes to clear().
    pid_t         mPid = -1;
    uid_t         mUid = -1;
    std::string   mPkgName;
    int64_t       mPkgVersionCode = 0;
    std::string   mKey;
    nsecs_t       mTimestamp = 0;
    std::map<std::string, Prop> mProps;
};

} // namespace mediametrics
} // namespace android

#endif // ANDROID_MEDIA_MEDIAMETRICSITEM_H
