/*
 * Copyright 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.
 */
package android.os;

import android.annotation.SystemApi;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

/**
 * Container for statsd dimension value information, corresponding to a
 * stats_log.proto's DimensionValue.
 *
 * This consists of a field (an int representing a statsd atom field)
 * and a value (which may be one of a number of types).
 *
 * <p>
 * Only a single value is held, and it is necessarily one of the following types:
 * {@link String}, int, long, boolean, float,
 * or tuple (i.e. {@link List} of {@code StatsDimensionsValue}).
 *
 * The type of value held can be retrieved using {@link #getValueType()}, which returns one of the
 * following ints, depending on the type of value:
 * <ul>
 *  <li>{@link #STRING_VALUE_TYPE}</li>
 *  <li>{@link #INT_VALUE_TYPE}</li>
 *  <li>{@link #LONG_VALUE_TYPE}</li>
 *  <li>{@link #BOOLEAN_VALUE_TYPE}</li>
 *  <li>{@link #FLOAT_VALUE_TYPE}</li>
 *  <li>{@link #TUPLE_VALUE_TYPE}</li>
 * </ul>
 * Alternatively, this can be determined using {@link #isValueType(int)} with one of these constants
 * as a parameter.
 * The value itself can be retrieved using the correct get...Value() function for its type.
 *
 * <p>
 * The field is always an int, and always exists; it can be obtained using {@link #getField()}.
 *
 *
 * @hide
 */
@SystemApi
public final class StatsDimensionsValue implements Parcelable {
    private static final String TAG = "StatsDimensionsValue";

    // Values of the value type correspond to stats_log.proto's DimensionValue fields.
    // Keep constants in sync with services/include/android/os/StatsDimensionsValue.h.
    /** Indicates that this holds a String. */
    public static final int STRING_VALUE_TYPE = 2;
    /** Indicates that this holds an int. */
    public static final int INT_VALUE_TYPE = 3;
    /** Indicates that this holds a long. */
    public static final int LONG_VALUE_TYPE = 4;
    /** Indicates that this holds a boolean. */
    public static final int BOOLEAN_VALUE_TYPE = 5;
    /** Indicates that this holds a float. */
    public static final int FLOAT_VALUE_TYPE = 6;
    /** Indicates that this holds a List of StatsDimensionsValues. */
    public static final int TUPLE_VALUE_TYPE = 7;

    /** Value of a stats_log.proto DimensionsValue.field. */
    private final int mField;

    /** Type of stats_log.proto DimensionsValue.value, according to the VALUE_TYPEs above. */
    private final int mValueType;

    /**
     * Value of a stats_log.proto DimensionsValue.value.
     * String, Integer, Long, Boolean, Float, or StatsDimensionsValue[].
     */
    private final Object mValue; // immutable or array of immutables

    /**
     * Creates a {@code StatsDimensionValue} from a parcel.
     *
     * @hide
     */
    public StatsDimensionsValue(Parcel in) {
        mField = in.readInt();
        mValueType = in.readInt();
        mValue = readValueFromParcel(mValueType, in);
    }

    /**
     * Return the field, i.e. the tag of a statsd atom.
     *
     * @return the field
     */
    public int getField() {
        return mField;
    }

    /**
     * Retrieve the String held, if any.
     *
     * @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE},
     *         null otherwise
     */
    public String getStringValue() {
        try {
            if (mValueType == STRING_VALUE_TYPE) return (String) mValue;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return null;
    }

    /**
     * Retrieve the int held, if any.
     *
     * @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise
     */
    public int getIntValue() {
        try {
            if (mValueType == INT_VALUE_TYPE) return (Integer) mValue;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return 0;
    }

    /**
     * Retrieve the long held, if any.
     *
     * @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise
     */
    public long getLongValue() {
        try {
            if (mValueType == LONG_VALUE_TYPE) return (Long) mValue;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return 0;
    }

    /**
     * Retrieve the boolean held, if any.
     *
     * @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE},
     *         false otherwise
     */
    public boolean getBooleanValue() {
        try {
            if (mValueType == BOOLEAN_VALUE_TYPE) return (Boolean) mValue;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return false;
    }

    /**
     * Retrieve the float held, if any.
     *
     * @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise
     */
    public float getFloatValue() {
        try {
            if (mValueType == FLOAT_VALUE_TYPE) return (Float) mValue;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return 0;
    }

    /**
     * Retrieve the tuple, in the form of a {@link List} of {@link StatsDimensionsValue}, held,
     * if any.
     *
     * @return the {@link List} of {@link StatsDimensionsValue} held
     *         if {@link #getValueType()} == {@link #TUPLE_VALUE_TYPE},
     *         null otherwise
     */
    public List<StatsDimensionsValue> getTupleValueList() {
        if (mValueType != TUPLE_VALUE_TYPE) {
            return null;
        }
        try {
            StatsDimensionsValue[] orig = (StatsDimensionsValue[]) mValue;
            List<StatsDimensionsValue> copy = new ArrayList<>(orig.length);
            // Shallow copy since StatsDimensionsValue is immutable anyway
            for (int i = 0; i < orig.length; i++) {
                copy.add(orig[i]);
            }
            return copy;
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
            return null;
        }
    }

    /**
     * Returns the constant representing the type of value stored, namely one of
     * <ul>
     *   <li>{@link #STRING_VALUE_TYPE}</li>
     *   <li>{@link #INT_VALUE_TYPE}</li>
     *   <li>{@link #LONG_VALUE_TYPE}</li>
     *   <li>{@link #BOOLEAN_VALUE_TYPE}</li>
     *   <li>{@link #FLOAT_VALUE_TYPE}</li>
     *   <li>{@link #TUPLE_VALUE_TYPE}</li>
     * </ul>
     *
     * @return the constant representing the type of value stored
     */
    public int getValueType() {
        return mValueType;
    }

    /**
     * Returns whether the type of value stored is equal to the given type.
     *
     * @param valueType int representing the type of value stored, as used in {@link #getValueType}
     * @return true if {@link #getValueType()} is equal to {@code valueType}.
     */
    public boolean isValueType(int valueType) {
        return mValueType == valueType;
    }

    /**
     * Returns a String representing the information in this StatsDimensionValue.
     * No guarantees are made about the format of this String.
     *
     * @return String representation
     *
     * @hide
     */
    // Follows the format of statsd's dimension.h toString.
    public String toString() {
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(mField);
            sb.append(":");
            if (mValueType == TUPLE_VALUE_TYPE) {
                sb.append("{");
                StatsDimensionsValue[] sbvs = (StatsDimensionsValue[]) mValue;
                for (int i = 0; i < sbvs.length; i++) {
                    sb.append(sbvs[i].toString());
                    sb.append("|");
                }
                sb.append("}");
            } else {
                sb.append(mValue.toString());
            }
            return sb.toString();
        } catch (ClassCastException e) {
            Slog.w(TAG, "Failed to successfully get value", e);
        }
        return "";
    }

    /**
     * Parcelable Creator for StatsDimensionsValue.
     */
    public static final Parcelable.Creator<StatsDimensionsValue> CREATOR = new
            Parcelable.Creator<StatsDimensionsValue>() {
                public StatsDimensionsValue createFromParcel(Parcel in) {
                    return new StatsDimensionsValue(in);
                }

                public StatsDimensionsValue[] newArray(int size) {
                    return new StatsDimensionsValue[size];
                }
            };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mField);
        out.writeInt(mValueType);
        writeValueToParcel(mValueType, mValue, out, flags);
    }

    /** Writes mValue to a parcel. Returns true if succeeds. */
    private static boolean writeValueToParcel(int valueType, Object value, Parcel out, int flags) {
        try {
            switch (valueType) {
                case STRING_VALUE_TYPE:
                    out.writeString((String) value);
                    return true;
                case INT_VALUE_TYPE:
                    out.writeInt((Integer) value);
                    return true;
                case LONG_VALUE_TYPE:
                    out.writeLong((Long) value);
                    return true;
                case BOOLEAN_VALUE_TYPE:
                    out.writeBoolean((Boolean) value);
                    return true;
                case FLOAT_VALUE_TYPE:
                    out.writeFloat((Float) value);
                    return true;
                case TUPLE_VALUE_TYPE: {
                    StatsDimensionsValue[] values = (StatsDimensionsValue[]) value;
                    out.writeInt(values.length);
                    for (int i = 0; i < values.length; i++) {
                        values[i].writeToParcel(out, flags);
                    }
                    return true;
                }
                default:
                    Slog.w(TAG, "readValue of an impossible type " + valueType);
                    return false;
            }
        } catch (ClassCastException e) {
            Slog.w(TAG, "writeValue cast failed", e);
            return false;
        }
    }

    /** Reads mValue from a parcel. */
    private static Object readValueFromParcel(int valueType, Parcel parcel) {
        switch (valueType) {
            case STRING_VALUE_TYPE:
                return parcel.readString();
            case INT_VALUE_TYPE:
                return parcel.readInt();
            case LONG_VALUE_TYPE:
                return parcel.readLong();
            case BOOLEAN_VALUE_TYPE:
                return parcel.readBoolean();
            case FLOAT_VALUE_TYPE:
                return parcel.readFloat();
            case TUPLE_VALUE_TYPE: {
                final int sz = parcel.readInt();
                StatsDimensionsValue[] values = new StatsDimensionsValue[sz];
                for (int i = 0; i < sz; i++) {
                    values[i] = new StatsDimensionsValue(parcel);
                }
                return values;
            }
            default:
                Slog.w(TAG, "readValue of an impossible type " + valueType);
                return null;
        }
    }
}
