/*
 * Copyright (C) 2018 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.
 */
#pragma once

#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "annotations.h"

namespace android {
namespace os {
namespace statsd {

class HashableDimensionKey;
struct Matcher;
struct Field;
struct FieldValue;

const int32_t kAttributionField = 1;
const int32_t kMaxLogDepth = 2;
const int32_t kLastBitMask = 0x80;
const int32_t kClearLastBitDeco = 0x7f;
const int32_t kClearAllPositionMatcherMask = 0xffff00ff;

enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };

int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);

int32_t encodeMatcherMask(int32_t mask[], int32_t depth);

// Get the encoded field for a leaf with a [field] number at depth 0;
inline int32_t getSimpleField(size_t field) {
    return ((int32_t)field << 8 * 2);
}

/**
 * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
 * proto.
 * [mTag]: the atom id.
 * [mField]: encoded path from the root (atom) to leaf.
 *
 * For example:
 * WakeLockStateChanged {
 *    repeated AttributionNode = 1;
 *    int state = 2;
 *    string tag = 3;
 * }
 * Read from logd, the items are structured as below:
 * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
 *
 * When we read through the list, we will encode each field in a 32bit integer.
 * 8bit segments   |--------|--------|--------|--------|
 *                    Depth   field0 [L]field1 [L]field1
 *
 *  The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
 *  The following 3 8-bit are for the item's position at each level.
 *  The first bit of each 8bits field is reserved to mark if the item is the last item at that level
 *  this is to make matching easier later.
 *
 *  The above wakelock event is translated into FieldValue pairs.
 *  0x02010101->1000
 *  0x02010182->tag
 *  0x02018201->2000
 *  0x02018282->tag2
 *  0x00020000->2
 *  0x00030000->"hello"
 *
 *  This encoding is the building block for the later operations.
 *  Please see the definition for Matcher below to see how the matching is done.
 */
struct Field {
private:
    int32_t mTag;
    int32_t mField;

public:
    Field() {}

    Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
        mField = getEncodedField(pos, depth, true);
    }

    Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
    }

    Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};

    inline void setField(int32_t field) {
        mField = field;
    }

    inline void setTag(int32_t tag) {
        mTag = tag;
    }

    inline void decorateLastPos(int32_t depth) {
        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
        mField |= mask;
    }

    inline int32_t getTag() const {
        return mTag;
    }

    inline int32_t getDepth() const {
        return (mField >> 24);
    }

    inline int32_t getPath(int32_t depth) const {
        if (depth > 2 || depth < 0) return 0;

        int32_t field = (mField & 0x00ffffff);
        int32_t mask = 0xffffffff;
        return (field & (mask << 8 * (kMaxLogDepth - depth)));
    }

    inline int32_t getPrefix(int32_t depth) const {
        if (depth == 0) return 0;
        return getPath(depth - 1);
    }

    inline int32_t getField() const {
        return mField;
    }

    inline int32_t getRawPosAtDepth(int32_t depth) const {
        int32_t field = (mField & 0x00ffffff);
        int32_t shift = 8 * (kMaxLogDepth - depth);
        int32_t mask = 0xff << shift;

        return (field & mask) >> shift;
    }

    inline int32_t getPosAtDepth(int32_t depth) const {
        return getRawPosAtDepth(depth) & kClearLastBitDeco;
    }

    // Check if the first bit of the 8-bit segment for depth is 1
    inline bool isLastPos(int32_t depth) const {
        int32_t field = (mField & 0x00ffffff);
        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
        return (field & mask) != 0;
    }

    // if the 8-bit segment is all 0's
    inline bool isAnyPosMatcher(int32_t depth) const {
        return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
    }
    // if the 8bit is 0x80 (1000 0000)
    inline bool isLastPosMatcher(int32_t depth) const {
        return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
    }

    inline bool operator==(const Field& that) const {
        return mTag == that.getTag() && mField == that.getField();
    };

    inline bool operator!=(const Field& that) const {
        return mTag != that.getTag() || mField != that.getField();
    };

    bool operator<(const Field& that) const {
        if (mTag != that.getTag()) {
            return mTag < that.getTag();
        }

        if (mField != that.getField()) {
            return mField < that.getField();
        }

        return false;
    }

    bool matches(const Matcher& that) const;
};

/**
 * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
 *
 * It contains all information needed to match one or more leaf node.
 * All information is encoded in a Field(2 ints) and a bit mask(1 int).
 *
 * For example, to match the first/any/last uid field in attribution chain in Atom 10,
 * we have the following FieldMatcher in statsd_config
 *    FieldMatcher {
 *        field:10
 *         FieldMatcher {
 *              field:1
 *              position: any/last/first
 *              FieldMatcher {
 *                  field:1
 *              }
 *          }
 *     }
 *
 * We translate the FieldMatcher into a Field, and mask
 * First: [Matcher Field] 0x02010101  [Mask]0xff7f7f7f
 * Last:  [Matcher Field] 0x02018001  [Mask]0xff7f807f
 * Any:   [Matcher Field] 0x02010001  [Mask]0xff7f007f
 * All:   [Matcher Field] 0x02010001  [Mask]0xff7f7f7f
 *
 * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
 * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
 * equal. Nothing can beat the performance of this matching algorithm.
 *
 * TODO(b/110561213): ADD EXAMPLE HERE.
 */
struct Matcher {
    Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};

    const Field mMatcher;
    const int32_t mMask;

    inline const Field& getMatcher() const {
        return mMatcher;
    }

    inline int32_t getMask() const {
        return mMask;
    }

    inline int32_t getRawMaskAtDepth(int32_t depth) const {
        int32_t field = (mMask & 0x00ffffff);
        int32_t shift = 8 * (kMaxLogDepth - depth);
        int32_t mask = 0xff << shift;

        return (field & mask) >> shift;
    }

    bool hasAllPositionMatcher() const {
        return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
    }

    bool hasAnyPositionMatcher(int* prefix) const {
        if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
            (*prefix) = mMatcher.getPrefix(1);
            return true;
        }
        return false;
    }

    inline bool operator!=(const Matcher& that) const {
        return mMatcher != that.getMatcher() || mMask != that.getMask();
    }

    inline bool operator==(const Matcher& that) const {
        return mMatcher == that.mMatcher && mMask == that.mMask;
    }
};

inline Matcher getSimpleMatcher(int32_t tag, size_t field) {
    return Matcher(Field(tag, getSimpleField(field)), 0xff7f0000);
}

inline Matcher getFirstUidMatcher(int32_t atomId) {
    int32_t pos[] = {1, 1, 1};
    return Matcher(Field(atomId, pos, 2), 0xff7f7f7f);
}

/**
 * A wrapper for a union type to contain multiple types of values.
 *
 */
struct Value {
    Value() : type(UNKNOWN) {}

    Value(int32_t v) {
        int_value = v;
        type = INT;
    }

    Value(int64_t v) {
        long_value = v;
        type = LONG;
    }

    Value(float v) {
        float_value = v;
        type = FLOAT;
    }

    Value(double v) {
        double_value = v;
        type = DOUBLE;
    }

    Value(const std::string& v) {
        str_value = v;
        type = STRING;
    }

    Value(const std::vector<uint8_t>& v) {
        storage_value = v;
        type = STORAGE;
    }

    void setInt(int32_t v) {
        int_value = v;
        type = INT;
    }

    void setLong(int64_t v) {
        long_value = v;
        type = LONG;
    }

    void setFloat(float v) {
        float_value = v;
        type = FLOAT;
    }

    void setDouble(double v) {
        double_value = v;
        type = DOUBLE;
    }

    union {
        int32_t int_value;
        int64_t long_value;
        float float_value;
        double double_value;
    };
    std::string str_value;
    std::vector<uint8_t> storage_value;

    Type type;

    std::string toString() const;

    bool isZero() const;

    Type getType() const {
        return type;
    }

    double getDouble() const;

    Value(const Value& from);

    bool operator==(const Value& that) const;
    bool operator!=(const Value& that) const;

    bool operator<(const Value& that) const;
    bool operator>(const Value& that) const;
    bool operator>=(const Value& that) const;
    Value operator-(const Value& that) const;
    Value& operator+=(const Value& that);
    Value& operator=(const Value& that);
};

class Annotations {
public:
    Annotations() {
        setNested(true);  // Nested = true by default
    }

    // This enum stores where particular annotations can be found in the
    // bitmask. Note that these pos do not correspond to annotation ids.
    enum {
        NESTED_POS = 0x0,
        PRIMARY_POS = 0x1,
        EXCLUSIVE_POS = 0x2,
        UID_POS = 0x3
    };

    inline void setNested(bool nested) { setBitmaskAtPos(NESTED_POS, nested); }

    inline void setPrimaryField(bool primary) { setBitmaskAtPos(PRIMARY_POS, primary); }

    inline void setExclusiveState(bool exclusive) { setBitmaskAtPos(EXCLUSIVE_POS, exclusive); }

    inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); }

    inline void setResetState(int32_t resetState) {
        mResetState = resetState;
    }

    // Default value = false
    inline bool isNested() const { return getValueFromBitmask(NESTED_POS); }

    // Default value = false
    inline bool isPrimaryField() const { return getValueFromBitmask(PRIMARY_POS); }

    // Default value = false
    inline bool isExclusiveState() const { return getValueFromBitmask(EXCLUSIVE_POS); }

    // Default value = false
    inline bool isUidField() const { return getValueFromBitmask(UID_POS); }

    // If a reset state is not sent in the StatsEvent, returns -1. Note that a
    // reset satate is only sent if and only if a reset should be triggered.
    inline int32_t getResetState() const {
        return mResetState;
    }

private:
    inline void setBitmaskAtPos(int pos, bool value) {
        mBooleanBitmask &= ~(1 << pos); // clear
        mBooleanBitmask |= (value << pos); // set
    }

    inline bool getValueFromBitmask(int pos) const {
        return (mBooleanBitmask >> pos) & 0x1;
    }

    // This is a bitmask over all annotations stored in boolean form. Because
    // there are only 4 booleans, just one byte is required.
    uint8_t mBooleanBitmask = 0;

    int32_t mResetState = -1;
};

/**
 * Represents a log item, or a dimension item (They are essentially the same).
 */
struct FieldValue {
    FieldValue() {}
    FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
    }
    bool operator==(const FieldValue& that) const {
        return mField == that.mField && mValue == that.mValue;
    }
    bool operator!=(const FieldValue& that) const {
        return mField != that.mField || mValue != that.mValue;
    }
    bool operator<(const FieldValue& that) const {
        if (mField != that.mField) {
            return mField < that.mField;
        }

        if (mValue != that.mValue) {
            return mValue < that.mValue;
        }

        return false;
    }

    Field mField;
    Value mValue;
    Annotations mAnnotations;
};

bool HasPositionANY(const FieldMatcher& matcher);
bool HasPositionALL(const FieldMatcher& matcher);

bool isAttributionUidField(const FieldValue& value);

/* returns uid if the field is uid field, or -1 if the field is not a uid field */
int getUidIfExists(const FieldValue& value);

void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);

bool isAttributionUidField(const Field& field, const Value& value);
bool isUidField(const FieldValue& fieldValue);

bool equalDimensions(const std::vector<Matcher>& dimension_a,
                     const std::vector<Matcher>& dimension_b);

// Returns true if dimension_a is a subset of dimension_b.
bool subsetDimensions(const std::vector<Matcher>& dimension_a,
                      const std::vector<Matcher>& dimension_b);
}  // namespace statsd
}  // namespace os
}  // namespace android
